PDA

Просмотр полной версии : Кардинальный метод защиты от XSS и атак по подстановке SQL-запросов


Suicide
17.06.2010, 06:00
Ден Каминский (Dan Kaminsky), получивший известность обнаружением фундаментальной уязвимости в DNS, представил универсальную технику защиты от "SQL Injection" (подстановка SQL-запросов) и XSS (межсайтовый скриптинг) атак. Суть техники защиты от подстановки SQL-запросов в том, что при работе с пользовательскими данными в запросе к СУБД фигурируют не открытые данные, а строка в base64-представлении, в которой изначально отсутствуют спецсимволы. В отличие от традиционной практики анализа вводимых пользователем данных и экранирования опасных символов перед формированием запроса, метод Каминского по своей сути исключает человеческий фактор и возможность недосмотра при проверке.

Для наглядности рассмотрим пример. Допустим в программе имеется строка

$conn->query("select * from table where fname=$fname;");

в случае отсутствия должных проверок в переменной $fname может оказаться SQL-код, т.е. имеет место классическая "SQL Injection" уязвимость. Следуя методике Каминского, поменяв данную конструкцию на

$conn->query(eval(b('select * from table where fname=^^fname;')));

, где "b" - функция враппер для подстановки операций base64-кодирования для переменных, отмеченных через маркер "^^". В итоге к СУБД будет сформирован запрос:

select * from table where fname=b64d("VehHU.....=")


как видим, какое бы ни было содержимое переменной fname при обращении к СУБД оно будет всегда представлено валидной строкой, которая будет перекодирована из base64-представления уже силами СУБД.

Похожая техника предлагается и для защиты от XSS-атак, все выводимые на страницу блоки данных изначально поступают в base64-представлении и отображаются через задействование специального JavaScript-враппера, декодирующего base64-строку и выводящего блок в заданную позицию без его интерпретации браузером.

Пример с реализацией необходимых для осуществления защиты функций на языках PHP и JavaScript, а также дополнение к MySQL с функциями обработки строк base64 (в PostgreSQL поддержка base64 реализована через штатные функции encode/decode), доступны для свободной загрузки (http://recursion.com/interpolique.html). Презентацию с подробным описанием метода можно посмотреть http://www.scribd.com/doc/33001026/Interpolique.

17.06.2010
http://www.opennet.ru/opennews/art.shtml?num=26997

http://www.darkreading.com/database_security/security/app-security/showArticle.jhtml?articleID=225700088

Nightmarе
17.06.2010, 06:20
На первый взгляд кажется глупо. Могу и ошибаться.

$conn->query(eval(b('select * from table where fname=^^fname;')));

опять таки это в КАЖДЫЙ запрос надо вставлять, а не проще тогда юзать real escape string для каждого запроса?

Вот было бы что-то глобальное, как например способ с .htaccess который полностью фильтрует весь сайт целиком, тогда было бы интереснее.

DoN
17.06.2010, 10:34
оке. теперь горик-второй подождем это в бд

vvs777
17.06.2010, 11:34
защита от ламо-кодеров ценой увеличения CPU time

wildshaman
17.06.2010, 11:39
почему многие считают, что проще написать такую страшную обертку, чем просто заюзать пару простых стандартных функций.Тем более, строки, числа, другие входные данные надо обрабатывать по-разному.

Qwazar
17.06.2010, 11:45
Мда, ну и глупость этот чел предложил.

SQLHACK
17.06.2010, 13:45
А че за функция b() ТО, искал искал ,так и не нашел , че за врапер, просто там еще eval добавляется, мож там еще испонения кода гденить есть ?*

Pashkela
17.06.2010, 14:08
Хыыыыыыыыы!!!! Особые обстоятельства детектед!!! Ми просто смотрю в будущее

Twoster
17.06.2010, 14:11
я что то совсем не понял! =(
select * from table where fname=b64d("VehHU.....=")

получается, что я ему отправляю запрос вида
select * from table where fname=b64d("Jw==")
после преобразования получится один фиг
select * from table where fname='
? =\


UPDATE:

все, понял
которая будет перекодирована из base64-представления уже силами СУБД.

т.е. помимо использования функций в пхп, еще нужно переписать сорцы всех субд?

З.Ы. Этот треш на равне с БолдженОС прямо... каникулы чтоли такие

Rebz
17.06.2010, 14:15
Метод оказался слишком кардинальным для Античата :\

Twoster
17.06.2010, 14:20
Метод оказался слишком кардинальным для Античата :\
Обидно просто, что реально умные вещи наших ребят остаются потеряным постом в статьях и "Вопросах по уязвимостям", а вот такие вот горе-дефенсеры пиарятся на пустом месте, причем и за счет нашего форума тоже...
И еще обидно за низкую квалификацию специалистов-корреспондентов! =\ упомяну опять же ту же BolgenOS, такую туфту пропустили в массы, распиарили.. неужели в XXI веке нельзя найти сотрудника, имеющего хорошее IT образование? =\

rebus2
17.06.2010, 14:37
Обидно просто, что реально умные вещи наших ребят остаются потеряным постом в статьях и "Вопросах по уязвимостям"

Никто не забыт и не что не забыто :D

Ну нашли что-то, расковыряли, отписали ну и хорошо ну и правильно.. кому надо тот докапаеться и прочтет.. и будет юзать и будет благодарен..

тут наверно работает какой-то принцип всемирного уравновешивания.. еслиб все хорошие мысли по безопасности реализовывались тоже б не чего хорошего не было.. сколько и так дыр каждый день затыкают..

Jokester
17.06.2010, 14:37
Мда, ну и глупость этот чел предложил.
+1

Ден Каминский (Dan Kaminsky), получивший известность обнаружением фундаментальной уязвимости в DNS оказался не таким уж толковым парнем, судя по этому материалу :)

Для нормальных кодеров "проблемы SQL инъекций" вообще нет, ибо они знают как работать с данными.

Ну а если кому-то не хватает стандартных функций пыха давно придумали PDO

Nightmarе
17.06.2010, 15:55
неужели в XXI веке нельзя найти сотрудника, имеющего хорошее IT образование? =\
Помоему как раз по этому критерию на работу то и набирают "спецов" с купленными дипломами.
Тут необходима в первую очередь увлеченность своим делом, а не желание заработать выдавая себя за спеца по безопасности.
Все вопросы сами собой отпадали бы, если бы в компаниях всех этих горе-спецов тестировали как они борятся с уязвимостями, смотрели бы как они пишут код, специально подталкивая их к уязвимым функциям и т.д...

Об этом например говорит тот факт, что почти во всех SQL есть вывод ошибки. ($mysql_error), то бишь всё просто копипастят из инета, берут функции и просто юзают их, а в инете как известно никаких фильтров в примерах то и не стоит.

ghostwizard
17.06.2010, 15:58
Хорош метод. Все, что достаточно, это пропатчить модуль на php (mysql.so), perl (dbi::mysql), python (не помню) и что там еще у вас, где функция сразу кодировала строку запроса и после отдавала драйверу на обработку. ИМХО, решение имеет место быть, причем начнет действовать сразу и глобально без надобности переписывать весь код.

Qwazar
17.06.2010, 16:12
Хорош метод. Все, что достаточно, это пропатчить модуль на php (mysql.so), perl (dbi::mysql), python (не помню) и что там еще у вас, где функция сразу кодировала строку запроса и после отдавала драйверу на обработку. ИМХО, решение имеет место быть, причем начнет действовать сразу и глобально без надобности переписывать весь код. Тогда уж PDO (как написал Jokester), а иначе, как ты в драйвере будешь определять какую часть запроса пользователь наколбасил руками, а какую взял из параметров полученных извне?

Это я к тому, что твой вариант не пашет.

P.S.
Речь только о php, в случае с Java или .Net наличие SQL инъекций вообще непростительно.

ghostwizard
17.06.2010, 16:30
Тогда уж PDO (как написал Jokester), а иначе, как ты в драйвере будешь определять какую часть запроса пользователь наколбасил руками, а какую взял из параметров полученных извне?

Это я к тому, что твой вариант не пашет.


Логично, об этом я не подумал... В любом случае было и такое:
http://bugs.mysql.com/bug.php?id=18861

Я вообще сторонник жестких проверок передаваемых значений. Не проще ли тогда делать так:

$resname = b64function($fname);
$conn->query(select * from table1 where fname=$resname)

?

Qwazar
17.06.2010, 16:37
Логично, об этом я не подумал... В любом случае было и такое:
http://bugs.mysql.com/bug.php?id=18861

Я вообще сторонник жестких проверок передаваемых значений. Не проще ли тогда делать так:

$resname = b64function($fname);
$conn->query(select * from table1 where fname=$resname)

? Погугли на тему PDO, в частности binding parameters.

ghostwizard
17.06.2010, 16:40
Погугли на тему PDO, в частности binding parameters.

Спасибо буду иметь ввиду, на php не программирую сейчас :). Вообще в линке, что я дал есть патч весьма свежий (для 5.х из рассылки) именно для mysql, который включает в себя встроенные функции для кодирования/декодирования.