The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

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

17.06.2010 00:06

Ден Каминский (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), доступны для свободной загрузки. Презентацию с подробным описанием метода можно посмотреть здесь.

  1. Главная ссылка к новости (http://www.darkreading.com/dat...)
  2. OpenNews: Иллюстрированное пояснение сущности атаки на DNS серверы
  3. OpenNews: Фундаментальная уязвимость в DNS. Рекомендуется срочно обновить BIND
  4. OpenNews: Опубликован код эксплоита для атаки на DNS серверы
Лицензия: CC BY 3.0
Короткая ссылка: https://opennet.ru/26997-security
Ключевые слова: security, xss, sql
При перепечатке указание ссылки на opennet.ru обязательно


Обсуждение (97) Ajax | 1 уровень | Линейный | +/- | Раскрыть всё | RSS
  • 1.1, Аноним (-), 00:40, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • –8 +/
    Зачем это?
    А внешних кавычек ($conn->query("select * from table where fname=\"$fname\";");) и isset($fname) недостаточно?
     
     
  • 2.3, XoRe (ok), 00:49, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +2 +/
    >А внешних кавычек ($conn->query("select * from table where fname=\"$fname\";");) и isset($fname) недостаточно?

    $fname = 'xxx"; delete from table; select "goodbye';
    $conn->query("select * from table where fname=\"$fname\";");

    Подставьте вместо table - название имеющейся таблицы и запустите у себя в базе данных.
    Хотя, не знаю, выполнит ли он все три запроса - это уже зависит от языка, интерфейса к БД и т.д.

     
  • 2.98, Аноним (-), 21:26, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > Зачем это?
    > А внешних кавычек ($conn->query("select * from table where fname=\"$fname\";");) и
    > isset($fname) недостаточно?

    PHP-программисты такие програссимты...

    ясное дело что подставление ковычек -- НЕ запускает процесс экранирования :-D !

    в Python DB-API-2.0 -- всё сделано для людей:

    c.execute('SELECT * FROM stocks WHERE symbol=?', (symbol,))

    вот вам и решение проблемы с безопасностью от инъекций

     
     
  • 3.102, Kibab (ok), 09:34, 21/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    В PHP достаточно юзать PDO и bindColumn()-методы для достижения того же самого результата. Сделано для людей (с) Вы.
     

  • 1.2, XoRe (ok), 00:42, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    Очень интересно.
    Просто и гениально.
    Хотя все сводится к тому, что программисты в обязательном порядке станут писать код для обработки данных в sql запросе.
    Пусть даже в автоматическом режиме, благодаря врапперу.
    Но идея хороша.
    Увеличение размера переменных на 30% - фигня по сравнению с безопасностью.

    P.S.
    $conn->query("select * from table where fname=$fname;");
    А так пишут?
    Без парсинга переменной и без кавычек?)

    UPD:
    По комментарию выше понял, что пишут =)

     
     
  • 2.7, _Vitaly_ (ok), 01:14, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +4 +/
    По-моему он экранирование переизобрел.

    И даже если принять синтаксис ^^, непонятно зачем парсером заворачивать аж в base64 вместо добавления слешей.

     
     
  • 3.19, Аноним (-), 04:23, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +2 +/
    >По-моему он экранирование переизобрел.

    В том-то и дело, что экранировать сплошь и рядом забывают или криво экранируют, поэтому тоннами и всплывают SQL Injection, даже во вполне больших проектах, в которых и разработчики не дураки и аудит проводится.

    http://secunia.com/advisories/search/?search=sql+injection

     
     
  • 4.41, zazik (ok), 10:30, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    А ещё можно экранировать при включенном автоэкранировании, тоже весело. Так что единственно верный подход - писать нормальный, безопасный код.
     
  • 4.56, _Vitaly_ (ok), 12:19, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +3 +/
    Когда разработчики не дураки, обычно запросы идут через прослойку, которая автоматически приведение типов и экранирование выполняет.

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

    А сама мысль о выделении переменных ^^ интересная, согласен.

     
     
  • 5.91, XoRe (ok), 11:24, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +4 +/
    Да суть-то в другом Чтобы была схема юзер что-то ввел в форму - оно кодируется... большой текст свёрнут, показать
     
     
  • 6.100, _Vitaly_ (ok), 00:15, 20/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Теперь просек. Действительно хороший выход для тех, кто без врапперов пишет.
     

  • 1.4, ffsdmad (ok), 01:00, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • –1 +/
    идея конечно гениальна
    НО
    если у меня в базе будут base64 закодированные данные, то select * from table where like '%query%' работать просто не будет и мне скажут нах.. зачем нам база без поиска?
    а если не хранить в base64 то смысла нет, так как подставить под base64 кавычки или join ни кто не мешает

    а для DNS хакера эта идея конечно хороша

     
     
  • 2.8, Alex (??), 01:16, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Base64 передается в только в запросе, завернутый в вызов функции преобразования.
    В базе хранится обычный текст, естественно.
     
     
  • 3.10, ffsdmad (ok), 01:20, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • –2 +/
    а какой смысл если после декодирования в запросе появится лишняя кавычка или join ?
     
     
  • 4.11, ffsdmad (ok), 01:22, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >а какой смысл если после декодирования в запросе появится лишняя кавычка или
    >join ?

    либо это должно быть встроено в субд, всмысле врапер, чтобы раскодированная строка уже не парсилась

     
     
  • 5.24, Аноним (-), 05:15, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +3 +/
    само собой, base64 декодируется уже внутри СУБД, средствами субд и представляет из себя только сроку, а не команду.
     
  • 2.20, Аноним (-), 04:27, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >а если не хранить в base64 то смысла нет, так как подставить
    >под base64 кавычки или join ни кто не мешает

    base64 всегда буквы и цифры, т.е. чтобы не делал в запросе всегда будут буквы и цифры, никаких кавычек не появятся. Посмотрите пример, к БД всегда уходят запросы типа fname=b64d("abc"), где abc строка в base64 формате, хоть ты туда изначально !@#$%^&* поместишь.

     

  • 1.5, ссс (?), 01:03, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • –1 +/
    непонятно, так если я введу например через веб-форму "' or '%" в переменную $fname, он закодирует мою инъекцию, раскодирует и выполнит мой код ВСЁ РАВНО. в чем прикол?
     
     
  • 2.6, ffsdmad (ok), 01:04, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    ... получивший известность обнаружением фундаментальной уязвимости в ...
     
  • 2.12, аноним (?), 01:43, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +2 +/
    Не выполнит.
     
  • 2.22, Аноним (-), 04:32, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >непонятно, так если я введу например через веб-форму "' or '%" в
    >переменную $fname, он закодирует мою инъекцию, раскодирует и выполнит мой код
    >ВСЁ РАВНО. в чем прикол?

    В запросе к базе будет вместо вашего "' or '%" - b64d("DSSDDQEd="), и уже СУБД декодирует DSSDDQEd= и будет воспринимать "' or '%" как константу, а не часть запроса.

     

  • 1.9, vvvua (ok), 01:18, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    А 2 года назад меня пытались заплевать...
    http://sql.ru/forum/actualthread.aspx?tid=616602
     
     
  • 2.13, аноним (?), 01:44, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • –1 +/
    >А 2 года назад меня пытались заплевать...
    >http://sql.ru/forum/actualthread.aspx?tid=616602

    А тебя и сейчас за это заплюют и правильно сделают.

     
  • 2.15, Аноним (-), 01:57, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Вы предгагаете сделать так:
    INSERT INTO table .. VALUES('_base64_enoded_string_');
    он предлагает:
    INSERT INTO table .. VALUES(base64_decode('_base64_enoded_string_'));

    Соответственно в вашем случае хранинся - b64, в его - чистый текст.
    Но, да, его вариант решает пробоему SQL-Inj ( по сути - проблему разбора SQL-запросов).
    Хотя, ихмо, использование подстановок с один раз написанным и отлаженным экранированием работает не хуже.

     
     
  • 3.23, Аноним (-), 04:34, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >Но, да, его вариант решает пробоему SQL-Inj ( по сути - проблему
    >разбора SQL-запросов).
    >Хотя, ихмо, использование подстановок с один раз написанным и отлаженным экранированием работает
    >не хуже.

    Практика показывает, что экранирование под давлением человеческого фактора совсем не работает, даже в Joomla криво экранируют и mod_security не помогает.

     
  • 2.17, pento (?), 02:01, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    И правильно заплевали.
    Ваше решение из разряда защитимся от XSS и для этого всё в базу будем ложить уже с заменой на HTML-мнемоники, тем самым портя данные. Это архитектурная ошибка может вам встать боком в самый неподходящий момент.
    Предложение Камински интересно, но не более. Не особо много преимуществ по сравнению с параметризованными запросами, а если у вас используется нормальный ORM, то такой проблемы вообще нет.

     
     
  • 3.18, Gambler (ok), 03:02, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Верно сказано.

    Чем эти методы лучше использования, скажем, PDO с параметрами и нормального эскейпера для вводимых пользователями данных? Хуже они тем, что усложнят запросы, раздуют размер передаваемых данных, а так же усложнят отладку. А передавать с вебсайты блоки данных, которые потом JavaScript будет декодировать и распихивать по тегами - вообще редкостное извращение. А если пользователям надо, скажем, запостить блок текста с жирным текстом и курсивом?

     
  • 3.72, vvvua (ok), 14:55, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >И правильно заплевали.
    >Ваше решение из разряда защитимся от XSS и для этого всё в
    >базу будем ложить уже с заменой на HTML-мнемоники, тем самым портя
    >данные. Это архитектурная ошибка может вам встать боком в самый неподходящий
    >момент.

    Вы ошиблись. Я не от XSS защищал, а от SQL injection. Это разные вещи. Кроме того, моё приложение на момент разработки ни имело ни малейшего отношения к HTML.
    И замена на HTML мнемоники не равноценна замене на base64, т.к. base64 не нарушает целостность данных.

     
     
  • 4.74, pento (ok), 15:52, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    gt оверквотинг удален 1 Я в курсе того, чем отличаются XSS от SQL-инъекции 2 ... большой текст свёрнут, показать
     
     
  • 5.96, vvvua (ok), 16:02, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    На счет костыльного решения - 100%. Что моё, что Камински.
    Я не приветствую решения, которые замедляют (читай увеличивают нагрузку на CPU) работу отдельных функций СУБД. Вот если создать работу со специндексами в самой СУБД (например, для полнотекстового поиска в кодировке base64 или подобной), которые будут работать не медленнее существующих - это уже будет не костыль, а фича!

     
  • 2.25, аноним (?), 06:39, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • –5 +/
    Лол! Base64 в целях безопасности, такого еще не было.
     
  • 2.39, FractalizeR (ok), 10:26, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Вы предлагали совсем другое. Глупо хранить в базе все строки в base64.
     
     
  • 3.71, vvvua (ok), 14:48, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • –1 +/
    >Вы предлагали совсем другое. Глупо хранить в базе все строки в base64.

    Как по мне, похожее предложение. Да, другая проверка на соответствие base64.
    На счёт глупо или нет - практика показала, что затруднен только полнотекстовый поиск (или частичный, как кому угодно). Всунуть мне левый запрос в принципе невозможно - я проверяю в приложении,которое работает с базой, на base64 соответствие.
    Кроме того, я не предлагал ВСЕ текстовые строки хранить в base64. Только те, которые участвуют в запросах из общедоступных приложений или сторонних продуктов, чье качество кодирования проверить затруднительно.


     
     
  • 4.73, FractalizeR (ok), 14:57, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >>Вы предлагали совсем другое. Глупо хранить в базе все строки в base64.
    >
    >Как по мне, похожее предложение. Да, другая проверка на соответствие base64.

    Читайте еще раз. Абсолютно не похожее.

     

  • 1.14, tonnzor (?), 01:45, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +5 +/
    Во всех нормальных библиотеках это происходит и так (псевдокод):

    $query = parse("select * from users where id = :users")
    $query->bind('users', $users);
    $query->execute();

    И в MySQL, и в Oracle такое есть.

     
     
  • 2.16, filosofem (ok), 01:59, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Автор это объясняет тем, что ни один програмер не пишет параметризированные запросы, кроме как под дулом пистолета. Якобы это сложнее, чем его костыль.
    Не исключено, что в некоторых случаях так и есть. Или например когда сервер достался от некрофилов с каким-нибудь php4.
     
     
  • 3.27, Sabitov (?), 06:51, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +3 +/
    Фигня :)

    Параметризованные запросы сильно ускоряют работу при использовании нормальных СУБД, даже безотносительно к безопасности. Кодеры, которые не используют таких запросов, должны лишаться ЗП в обязательном порядке! :)

    К сожалению, пыхпых 5 не умеет их поддерживать, если используется mysql, а не mysqli :( Но это уже другая песня.


     
     
  • 4.29, filosofem (ok), 08:22, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Зачем mysqli да, если есть выбор пиши под постгрес, не пожалеешь. =)
    И автора не обижайте, уверен, что он пошутил, насчет "никто не пишет".
     
  • 4.61, Pashugan (?), 13:07, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Раз уж пошла такая пьянка Есть неочевидный фактор, который заставляет меня ус... большой текст свёрнут, показать
     
     
  • 5.80, аноним (?), 17:19, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • –1 +/
    >Раз уж пошла такая пьянка... Есть не очевидный фактор, который заставляет меня усомниться в справедливости Вашей зарплаты. ;)

    Ты написал тупость, которая даже в мена костыле MySQL уже не соответствует действительности ...

    Простой вопрос на засыпку, что происходит (в нормальных DBMS) после того как парсер разобрал параметризованный запрос, но до того как ты забиндил значение и позвал экзекутор?
    Подсказка: ну хорошо - позвал ты экзекутор, что происходит дальше?


    Вот - вот, семь раз RTFM - один раз ...  :)

     
     
  • 6.86, Ivan1986 (?), 20:35, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Вообще написал он правильно - разница в скорости выполнения минимальна.
    Вызов функций биндинга даже чуть подороже, чем склейка строки + эскейпинг. Вобщем мы от этого отказались еще года два назад, когда только написал для симплы драйвер PDO, сначала написал с биндингом параметров, потом поставил опцию раскрытия симплой - получилось быстрее.

    Разумеется это не относится к циклу одинаковых запросов, но это настолько редкая ситуация, что смысла нету.

     
     
  • 7.92, onk (?), 11:44, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Вы в корне не правы (или правы в некотором частном случае)!
    может быть для MySQL это и правда, но приличные СУБД (в частности Oracle) _кешируют_ запросы после парсинга. в итоге запрос повторно разбирать не нужно!
    собственно число запросов в приложении конечно и при достаточном обьеме кеша у СУБД это неплого ускоряет работу.
     
     
  • 8.94, Pashugan (?), 14:52, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Так ли в корне он неправ Помимо времени на компиляцию запроса есть ещё фактор д... текст свёрнут, показать
     
  • 7.93, Pashugan (?), 14:39, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Я знаю, что правильно написал, потому что проверял это реальными тестами mysqli, а не просто занимался упражнениями в красноречии. :) Также я всегда готов выслушать обоснованные возражения и по-нормальному поспорить, чтобы докопаться до истины, но не вижу смысла отвечать анонимусам, которые готовы только гадить на голову коллег по цеху, но по существу вопроса ничего не пишут. :)
     
  • 6.97, tupka (?), 19:34, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >Вот - вот, семь раз RTFM - один раз ...  :)

    Семь раз RTFM, один раз rm -rf :D

     
  • 3.30, Ivan1986 (?), 09:08, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Полная чушь, если нормально реализовано, то никто просто не захочет писать не параметризованные запросы, так как они сильно упрощают код.

    В PDO как раз реализовано не нормально - синтаксис многословный.
    Посмотрите как реализовано тут - http://dklab.ru/lib/DbSimple/

    $db->select('select * from table where fname=? {AND id IN (?a)}', 'user', array(1,2,3));

    После использования такого синтаксиса как раз писать по старому будешь только под дулом пистолета.

     
     
  • 4.33, Lain_13 (?), 09:44, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Вся прелесть параметризованных запросов как-то в миг рушится, когда параметром оказывается часть имени таблицы. Ещё хуже, когда перестраиваются фрагменты запроса и в нём появляются/исчезают вложенные подзапросы и уровни вложенности этих запросов.
     
     
  • 5.37, ivan1986 (?), 10:06, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Сходите по ссылке

    'select * from ?_table' - префикс - по сути самый часто используемый вариант
    'select * from ?# where ...', 'tbl' - имя
    Вложенные подзапросы тоже есть, плюс в новой версии на форуме есть плейсхолдер подзапроса, можно творить такое, что я уже не знаю что туда можно добавить.

    http://forum.dklab.ru/viewtopic.php?p=180253#180253

    К сожалению либа была заброшена немного, но сейчас в составе фреймворка развивается
    https://sourceforge.net/projects/quickfw/

     
     
  • 6.81, аноним (?), 17:24, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >Сходите по ссылке
    >'select * from ?_table' - префикс - по сути самый часто используемый вариант

    Дык кто бы сомневался - творчеВство пехепешников - оно вообще вштыряет не по детски.

    То что такими гениальными запросами ставится на колени любая субд на любом железе уже "не проблемма кодера" да? :)


     
  • 4.43, filosofem (ok), 11:17, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Что именно чушь? Если СУБД не поддерживает параметризированные запросы, то никакой API их не сделает. Как вы собираетесь писать параметризированные запросы к какой-нибудь MSSQL 2k, или как вы будете делать аудит кода на php4, переписывать полностью на php5?

    ИМХО чушь это использовать на продакшне непонятные ноунэйм библиотеки. Вы проверяли, что эта DbSimple действительно делает параметризированные запросы? А вы уверены, что она так со всеми запросами будет делать? Или, что в ней нет многолетней дыры, которую просто некому заделывать, потому что никому не надо?
    То что в API выглядит запросом с параметрами, к СУБД может идти обычной строкой.

     
     
  • 5.44, ivan1986 (?), 11:25, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Я ее дописывал, а не только проверял.
    Что может - использует встроенные параметризации, что нет - раскрывает и сама экранирует.
    В случае, если параметры не поддерживаются, то конечно идет обычной экранируемой строкой.
    Почему-то в PDO нету подстановки в качестве параметров массивов, идентификаторов, и прочих полезных вещей.
     
     
  • 6.46, Аноним (-), 11:33, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >Я ее дописывал, а не только проверял.
    >Что может - использует встроенные параметризации, что нет - раскрывает и сама
    >экранирует.
    >В случае, если параметры не поддерживаются, то конечно идет обычной экранируемой строкой.
    >
    >Почему-то в PDO нету подстановки в качестве параметров массивов, идентификаторов, и прочих
    >полезных вещей.

    А вам не кажется, что использование "черного ящика", который то экранирует то параметоризирует, распускает разработчика, который начинает излишне доверять сторонней библиотеки, но по сути курит на бочке с порохом ? Я бы не стал доверять внешнему универсальному коду экранирования, например, дыры с недоэкранированием при передачи битого unicode классический пример, что и на старуху бывает проруха.

     
     
  • 7.48, ivan1986 (?), 11:44, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    А вам не кажется, что придумывание своего велосипеда, который хоть и известен до каждого винтика, но как всегда получится с квадратными колесами (доказано огромным количеством примером - столько CMS/форумов/фреймворков приделают в качестве доступа к базе такую фигню, что за голову берешься), взяли бы хоть PDO, и то лучше было бы.

    Экранируется кстати стандартными функциями - mysql_real_escape в случае mysql, pdo::quote в случае PDO, и так далее.

     
     
  • 8.50, Аноним (-), 11:49, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Вот видите, вы сами подтвердили мою гипотезу о том, что не стоит доверять внешни... текст свёрнут, показать
     
     
  • 9.52, ivan1986 (?), 11:59, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Вы только что доказали, что вы Аналитик с лора Тоесть вы предлагаете экраниров... текст свёрнут, показать
     
     
  • 10.55, Аноним (-), 12:17, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Я предлагаю не испытывать излишнего доверия к черным ящикам , так как в этом ли... текст свёрнут, показать
     
     
  • 11.57, ivan1986 (?), 12:34, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Понятно, позиция называется - пишем на ассемблере все Вы сейчас несете чушь - и... текст свёрнут, показать
     
     
  • 12.63, Аноним (-), 13:11, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Стоп, это же именно вы предлагайте использовать левую нестандартную библиотеку в... большой текст свёрнут, показать
     
     
  • 13.65, ivan1986 (?), 13:22, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Нет, я как раз предлагаю использовать стандартные функции - в случае mysql - mys... текст свёрнут, показать
     
     
  • 14.70, Аноним (-), 14:15, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Я пробовал принимать в mainstream - ... текст свёрнут, показать
     
  • 9.87, Sw00p aka Jerom (?), 20:48, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Release Date 2006-06-02... текст свёрнут, показать
     
  • 2.67, Аноним (-), 13:47, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Не вижу проблем писать код вида (псевдокод):
    $conn->query("SELECT * FROM table WHERE fname='".$conn->quote($fname)."'";

    Меня ни разу не обламывает экранировать переменные. Хотя, тут больше приходятся полагаться на внимание разработчика. Но, неужели сложно экранировать ВСЕ переменные, если нет уверенности в разработчике? Просто принять это как договорённость при разаработке проекта. А за неэкранированные больно бить по гениталиям.

    ИМХО, компактней, чем bind. Но о вкусах не спорят. ) Bind тоже катит. )

     
     
  • 3.75, Cobold (??), 16:13, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    вот тут-то как раз собака и порылась - если использовать биндинг то параметры всегда экранированы, совсем без участия разработчика, а если полагаться на экранирование "по ходу", то разработчик постоянно должен об этом думать (будто ему больше заняться нечем). В проекте с тысячами запросов это просто нереально, будь программисты хоть абсолютные педанты, кто угодно может забыть или просмотреть что-то. И случается это часто как раз в таких местах где визуально не сразу и заметишь, так что полагаться на то что другие коллеги обнаружат тоже нельзя. Поэтому такие дыры лучше ищутся автоматизированно, но тогда это уже аудит называется и стоит отдельно. Или жить с риском что кто-нибудь сделает это за тебя, но только тогда этот кто-то может отверстием сразу и попользоваться. А оно надо, весь этот гемморой?
     
     
  • 4.79, ivan1986 (?), 16:42, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Да, все правильно.
    По сути этоиу правилу удовлетворяет PDO, а симпла, про которую я писал выше - это доведенное до нормального интерфейса PDO.
     

  • 1.26, Аноним (-), 06:39, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    Вот в Постгрес есть такая тема, можно задавать любые ограничители типа $something$
    тоесть писать запросы типа select * from users where name=$pipiska$Вася$pipiska$;

    В похапе во входящих на всякий случай заменяем $pipiska$ на SpipiskaS и вставляем. Чем не метод?

     
  • 1.31, anthonio (ok), 09:24, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Это всё конечно интересно, да вот только ПМСМ нормальные программеры итак заботятся о безопасности и проверяют входные данные. Кто будет пользоваться этим методом, вас много наберётся?
     
     
  • 2.35, Аноним (-), 09:52, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Только нормальный программеров раз-два и обчелся, или их код обязательно будет р... большой текст свёрнут, показать
     
     
  • 3.36, anthonio (ok), 10:01, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >По вашему Drupal, Typo3, phpbb, Joomla и почти любой
    >другой крупный проект на PHP пишется спустя рукава ? Тем не
    >менее в них регулярно находят SQL Injection и баги, связанные с
    >отсутствием экранирования/проверки пользовательского ввода.

    Значит пишут спустя рукава. Или это PHP виноват? :)

     
     
  • 4.40, FractalizeR (ok), 10:27, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >>По вашему Drupal, Typo3, phpbb, Joomla и почти любой
    >>другой крупный проект на PHP пишется спустя рукава ? Тем не
    >>менее в них регулярно находят SQL Injection и баги, связанные с
    >>отсутствием экранирования/проверки пользовательского ввода.
    >
    >Значит пишут спустя рукава. Или это PHP виноват? :)

    А кто мешает писать спустя рукава с использованием именно этого метода? :) Разве мало мест где багов и дыр можно навешать, кроме этой, которую заткнете?

     
  • 3.38, ivan1986 (?), 10:20, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Вы считаете что у друпала или у джумлы хороший код?
    Блин, да достаточно посмотреть на их либы для работы с базами данных и уже понятно какие там "специалисты" сидят.
    Джумла вообще такое чувство что на коленке собрана, имел счастье копаться в ее коде...
     
     
  • 4.45, Аноним (-), 11:25, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >Вы считаете что у друпала или у джумлы хороший код?
    >Блин, да достаточно посмотреть на их либы для работы с базами данных
    >и уже понятно какие там "специалисты" сидят.
    >Джумла вообще такое чувство что на коленке собрана, имел счастье копаться в
    >ее коде...

    Давайте пойдем от обратного, можете привести пример качественного PHP-проекта, который более-менее распространен в сети ?

     
     
  • 5.49, ivan1986 (?), 11:47, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Ну например ZendFramework - довольно хороший код.
    Неплохой в кохане, правда не особо много видел, сужу только по той части, которую видел.
     
  • 5.51, ivan1986 (?), 11:53, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Вообще по части библиотеки доступа к базе данных - если при запросе к базе данных есть код вида

    $var = $db->escape($var);
    $db->query("..$var..");

    (тоесть можно передать неэкранированные данные просто забыв их экранировать)

    то это индикатор, что библиотека доступа к базе данных...

     

  • 1.32, Slautin (?), 09:27, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    Безумие какое-то... workaround для безграмотности.

    BTW - параметризованные запросы не просто делают код читабельным и избавляют от проблемы sql injection, но в разы (иногда в десятки раз) улучшают производительность запросов (парсинг sql, построение плана запроса...).

    "о сколько нам открытий чудных готовит просвященья дух...." ((c) А.Пушкин)

     
     
  • 2.54, Cobold (??), 12:15, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    если учесть сколько народу пишет для mysql, то там нативного биндинга нет и изза эмуляции производительность всётаки несколько падает, хотя и незначительно в сравнении с временем выполлнения запроса. А в остальнов полностью согласен, в плане безопасности ничего разумнее параметризированных запросов для sql пока не изобрели, да врядли изобретут. Да и автор статьи по сути предложил то-же самое, только таким вот странным способом.
     
  • 2.62, Pashugan (?), 13:11, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >BTW - параметризованные запросы не просто делают код читабельным и избавляют от
    >проблемы sql injection, но в разы (иногда в десятки раз) улучшают
    >производительность запросов (парсинг sql, построение плана запроса...).
    >
    >"о сколько нам открытий чудных готовит просвященья дух...." ((c) А.Пушкин)

    Иногда да, иногда нет. :) См. комментарий #61.

     
     
  • 3.90, Slautin (?), 09:22, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    > Иногда да, иногда нет. :) См. комментарий #61

    "нет", на мой взгляд, справедливо для очень узкого круга задач, обычно очень простых, для которых, действительно, не важна ни производительнсоть (и безопасность) ни здравый смысл.

    Но задача в пределах request-а обратиться одинаковым запросом минимум дважды - типовая и характерна для сколь нибудь существенных приложений, даже не очень сложных.

    ЗЫ: drupal, например, очень активно переходят на параметризованные запросы.
    Видимо, стало стыдно :)

     
     
  • 4.95, Pashugan (?), 15:35, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    :) Я как раз говорил, что в типичном скриптовом веб-приложении скорее всего будет "нет", и обращение к одному sql-запросу будет единожды. Потому что типичный http-запрос должен отработать на сервере по принципу "сделать как можно меньше и как можно быстрее умереть". Другое дело, что производительности можно достичь другими способами, а вот безопасность никогда не бывает лишней.
     

  • 1.42, ixti (ok), 11:15, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    ИМХО автор просто подошёл к проблеме интересным образом. Я не говорю, что он решил проблему в корне или что он изобрёл что-то гениальное. Просто действительно интересный вариант. И всё. Не думаю, что этот способ начнёт массово применяться в продакшене ;)) тем не менее значение его больше "а ещё это можно сделать так..."

    "...It's actually a model of the prison on Robin Island where Nelson Mandela was held 27 years ... Yeah. A lot of people don't realize this, but you can put your weed in there." (c) The Hot Chick

     
     
  • 2.89, Gambler (ok), 04:21, 18/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Верно, решение интересное. Возможно, что в каких-то других областях программирования его даже применят с пользой. Но как серьезное "улучшение" защиты от SQL инжекшенов это рассматривать нельзя.
     

  • 1.47, zuborg (?), 11:34, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    На самом деле действительно гениально и просто.

    Я бы, по крайней мере, до такого точно не додумался бы, поскольку пользуюсь prepare/bind/execute.

    Интересно, знает ли сам автор про биндинг переменных.

     
  • 1.53, Cobold (??), 12:06, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    совсем крыша поехала, вставлять eval и рассуждать о безопасности? Кроме того эта байда в такой форме работать не будет, надо бы на b() ещё и сами параметры передать.
     
  • 1.58, terr0rist (ok), 12:42, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    1. нифига этот метод не универсальный: а если запрос
    $conn->query("select * from $table where fname=XXX;");
    $table не получится base64-декодить =)
    2. Если есть такие товарищи, кто пишет where fname=$fname и register_globals=on - то им уже base64 не поможет, а поможет только кастрация мозга.
    3. В пхп вообще очень много универсальных решений для предотвращения sql-injection. Один magic_quotes_gpc чего стоит.
    4. Выше было замечено, что даже друпал и жумла пишутся "спустя рукава". Ну а что можно написать на пхп не спустя рукава? Какой нормальный программист будет использовать эту поделку, в которой какие-то переменные конфига меняют всю суть "языка", синтаксис понадёрган из 30 разных языков и то возможности, которые были изначально в других давно существующих языках, появляются только в версии 5.3, а ещё (при программистской лени) нужно зачем-то везде ставить эти $, ->, array() и прочие идиотские излишества. Код на пхп убог по сути пхп. И единственное универсальное средство против sql-injection для пхп - это отказ от пхп.
     
     
  • 2.59, ivan1986 (?), 12:53, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Последний вывод у вас странный.

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

    Фраза "даже друпал и жумла" некорректна - слово даже тут нельзя применять, это два примера феерически раскрученного отстоя.

    А язык хороший, не надо, просто на нем просто сделать криво, но это не значит что так нужно делать.

     
     
  • 3.64, Cobold (??), 13:17, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >[оверквотинг удален]
    >не будет вам в открытый доступ выкладывать хороший код - по
    >крайне мере очень редко.
    >А если пишется в соответствии с идеологией олпенсорса - каждый прикрутит маленькую
    >фигню, то и получается такой отстой как джумла или друпал.
    >
    >Фраза "даже друпал и жумла" некорректна - слово даже тут нельзя применять,
    >это два примера феерически раскрученного отстоя.
    >
    >А язык хороший, не надо, просто на нем просто сделать криво, но
    >это не значит что так нужно делать.

    Зря Вы так про опенсорс, просто бывают разные модели разработки. Бывает например разработка преимущественно силами комьюнити, там действительно так и получается, а бывает часто что фирма преимущественно или полностью своими силами разрабатывает, но выкладывает в открытый доступ потому что это сегодня выгодно во многих отношениях. Или даже некоммерческие проекты, но где одна более-менее постоянная комманда и один лидер тон задаёт. Загляните в код sugarcrm, рекомендую :)

     
     
  • 4.66, ivan1986 (?), 13:25, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Я так не про олпенсорс вообще, а про разработку силами комьюнити.
    Вот если разрабатывает одна фирма или команда получается как раз нормально.
    А когда приходит "комьюнити", то получается фигня.
     
  • 2.60, Cobold (??), 13:05, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +1 +/
    как-то довелось делать аудит для чужого проекта с тремя тысячами запросами по коду, чуть не каждый третий дырявый. Так вот главный программер с этой фирмочки уверял что у него magic_quotes_gpc включен и всё защищает. Про такие вещи как "select name from user where id=$id" он не подумал, что туда можно банально подзапрос в скобках вставить :)
     
  • 2.103, noname (??), 22:13, 21/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >4. Выше было замечено, что даже друпал и жумла пишутся "спустя рукава". Ну а что можно написать на пхп не спустя рукава? Какой нормальный программист будет использовать эту поделку, в которой какие-то переменные конфига меняют всю суть "языка", синтаксис понадёрган из 30 разных языков и то возможности, которые были изначально в других давно существующих языках, появляются только в версии 5.3, а ещё (при программистской лени) нужно зачем-то везде ставить эти $, ->, array() и прочие идиотские излишества. Код на пхп убог по сути пхп. И единственное универсальное средство против sql-injection для пхп - это отказ от пхп.

    А что бы вместо пхп предпочли вы?

     
  • 2.104, Kibab (ok), 19:49, 22/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    В то время, как такие, как Вы, орут об убогости пхп на форумах, нормальные разработчики зарабатывают деньги на написанных на пхп проектах :-)

    "Ах, Моська, знать, она сильна, что лает на слона..."

     

  • 1.69, Аноним (-), 14:02, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Ну, и ещё раз о главном (хоть, это возможно просто пример):
    За $conn->query("...fname=$fname...") надо больно бить по йайцам. Хотя бы, но не ограничиваясь (!) $conn->query("...where fname=".$fname."..."). Так переменную хоть заметней.
    на самом деле, это защита от неопытного/не очень грамотного кодера. Для больших проектов подойдёт.

    Хорошо бы без eval'ов и чтобы (без wrapper'а не срабатывало|wrapper применялся неявно). Но, в таком случае приходим как раз к bind'у.
    Короче - проект - не панацея. Тем более с eval'ами. )

     
     
  • 2.78, ivan1986 (?), 16:38, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    ха-ха-ха!

    За второй вариант по яйцам бить нужно так-же больно.

     

  • 1.76, Aleksey (??), 16:24, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Странно, что устроили такой холивар на пустом месте. Никто не заставляет вас использовать это в продакшене. Во время разработки напишите функцию MyEscape, которая в дебаге будет переводить аргумент в Base64, а в релизе вызывать функцию ескейпа. В базе данных разработчика повесить на вставку, обновление, удаление функцию расшифровки из base64. В результате вы на этапе разработки вы нигде не забудете делать экранирование.
     
     
  • 2.77, ivan1986 (?), 16:34, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    не смешно
     

  • 1.83, anonymous (??), 18:38, 17/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Способ конечно неплохой, но не всегда удобный.
    Кроме того, есть ещё такая вещь как "prepared statement".
     
     
  • 2.84, anonymous (??), 18:40, 17/06/2010 [^] [^^] [^^^] [ответить]  
  • +/
    Я хотел сказать: очень старый баян :)
     

  • 1.99, StrangeAttractor (ok), 21:27, 18/06/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Проблема в том, что base64 - по природе своей костыль. Если подумать, "экранировка", в общем-то, тоже. Надо копать в какую-то другую сторону, imho, отделять мух от котлет более радикально.
     
  • 1.105, RinNas (?), 12:48, 30/07/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    base64() ничем не лучше встроенных в БД методов квотирования, а минусы есть -- декодирование для БД не родное. Здесь Дэн облажался.
     

     Добавить комментарий
    Имя:
    E-Mail:
    Текст:



    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру