Ден Каминский (Dan Kaminsky (http://en.wikipedia.org/wiki/Dan_Kaminsky)), получивший известность обнаружением фундаментальной уязвимости в DNS, представил (http://recursion.com/interpolique.html) универсальную технику защиты от "SQL Injection" (подстановка SQL-запросов) и XSS (межсайтовый скриптинг) атак. Суть техники защиты от подстановки SQL-запросов в том, что при работе с пользовательскими данными в запросе к СУБД фигурируют не открытые данные, а строка в base64-представлении, в которой изначально отсутствуют спецсимволы. В отличие от традиционной практики анализа вводимых пользователем данных и экранирования опасных символов перед формированием запроса, метод Каминского по своей сути исключает человеческий фактор и возможность недосмотра при проверке.
Для наглядности рассмотрим пример. Допустим в программе имеется строка<font color="#461b7e"> $conn->query("select * from table where fname=$fname;");</font>
в случае отсутствия должных проверок в переменной $fname мо...
URL: http://www.darkreading.com/database_security/security/app-se...
Новость: http://www.opennet.me/opennews/art.shtml?num=26997
Зачем это?
А внешних кавычек ($conn->query("select * from table where fname=\"$fname\";");) и isset($fname) недостаточно?
>А внешних кавычек ($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 - название имеющейся таблицы и запустите у себя в базе данных.
Хотя, не знаю, выполнит ли он все три запроса - это уже зависит от языка, интерфейса к БД и т.д.
> Зачем это?
> А внешних кавычек ($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,))
вот вам и решение проблемы с безопасностью от инъекций
В PHP достаточно юзать PDO и bindColumn()-методы для достижения того же самого результата. Сделано для людей (с) Вы.
Очень интересно.
Просто и гениально.
Хотя все сводится к тому, что программисты в обязательном порядке станут писать код для обработки данных в sql запросе.
Пусть даже в автоматическом режиме, благодаря врапперу.
Но идея хороша.
Увеличение размера переменных на 30% - фигня по сравнению с безопасностью.P.S.
$conn->query("select * from table where fname=$fname;");
А так пишут?
Без парсинга переменной и без кавычек?)UPD:
По комментарию выше понял, что пишут =)
По-моему он экранирование переизобрел.И даже если принять синтаксис ^^, непонятно зачем парсером заворачивать аж в base64 вместо добавления слешей.
>По-моему он экранирование переизобрел.В том-то и дело, что экранировать сплошь и рядом забывают или криво экранируют, поэтому тоннами и всплывают SQL Injection, даже во вполне больших проектах, в которых и разработчики не дураки и аудит проводится.
http://secunia.com/advisories/search/?search=sql+injection
А ещё можно экранировать при включенном автоэкранировании, тоже весело. Так что единственно верный подход - писать нормальный, безопасный код.
Когда разработчики не дураки, обычно запросы идут через прослойку, которая автоматически приведение типов и экранирование выполняет.И тем не менее, вопрос о необходимости base64 остается открытым. Преимуществ перед слешами я пока не вижу, зато радостей по совместимости и изучению крякозябликов в логах будет вагон.
А сама мысль о выделении переменных ^^ интересная, согласен.
>Когда разработчики не дураки, обычно запросы идут через прослойку, которая автоматически приведение
>типов и экранирование выполняет.
>
>И тем не менее, вопрос о необходимости base64 остается открытым. Преимуществ перед
>слешами я пока не вижу, зато радостей по совместимости и изучению
>крякозябликов в логах будет вагон.
>
>А сама мысль о выделении переменных ^^ интересная, согласен.Да суть-то в другом.
Чтобы была схема:
юзер что-то ввел в форму - оно кодируется в base64 (на стороне клиента, а лучше - на стороне сервера) - передается в sql запрос в виде base64 - sql запрос уже сам декодирует и впихивает в поле.При такой схеме sql-injection не возможен в принципе.
Можно не беспокоиться об экранировании и приведении типов.
Вообще пох, что там введет юзер.
Хоть бинарные данные, символы с ascii номерами 0-31.
Единственное, что нужно проверять - это размер строки.
Но это уже из другой логики - из области переполнения буфера)
Кстати, всякие шеллкоды тоже не смогут пробраться, если на стороне сервера все приходящие переменные сразу кодировать в base64.Поэтому идея гениальна своей простотой и эффективностью.
Теперь просек. Действительно хороший выход для тех, кто без врапперов пишет.
идея конечно гениальна
НО
если у меня в базе будут base64 закодированные данные, то select * from table where like '%query%' работать просто не будет и мне скажут нах.. зачем нам база без поиска?
а если не хранить в base64 то смысла нет, так как подставить под base64 кавычки или join ни кто не мешаета для DNS хакера эта идея конечно хороша
Base64 передается в только в запросе, завернутый в вызов функции преобразования.
В базе хранится обычный текст, естественно.
а какой смысл если после декодирования в запросе появится лишняя кавычка или join ?
>а какой смысл если после декодирования в запросе появится лишняя кавычка или
>join ?либо это должно быть встроено в субд, всмысле врапер, чтобы раскодированная строка уже не парсилась
само собой, base64 декодируется уже внутри СУБД, средствами субд и представляет из себя только сроку, а не команду.
>а если не хранить в base64 то смысла нет, так как подставить
>под base64 кавычки или join ни кто не мешаетbase64 всегда буквы и цифры, т.е. чтобы не делал в запросе всегда будут буквы и цифры, никаких кавычек не появятся. Посмотрите пример, к БД всегда уходят запросы типа fname=b64d("abc"), где abc строка в base64 формате, хоть ты туда изначально !@#$%^&* поместишь.
непонятно, так если я введу например через веб-форму "' or '%" в переменную $fname, он закодирует мою инъекцию, раскодирует и выполнит мой код ВСЁ РАВНО. в чем прикол?
... получивший известность обнаружением фундаментальной уязвимости в ...
Не выполнит.
>непонятно, так если я введу например через веб-форму "' or '%" в
>переменную $fname, он закодирует мою инъекцию, раскодирует и выполнит мой код
>ВСЁ РАВНО. в чем прикол?В запросе к базе будет вместо вашего "' or '%" - b64d("DSSDDQEd="), и уже СУБД декодирует DSSDDQEd= и будет воспринимать "' or '%" как константу, а не часть запроса.
А 2 года назад меня пытались заплевать...
http://sql.ru/forum/actualthread.aspx?tid=616602
>А 2 года назад меня пытались заплевать...
>http://sql.ru/forum/actualthread.aspx?tid=616602А тебя и сейчас за это заплюют и правильно сделают.
Вы предгагаете сделать так:
INSERT INTO table .. VALUES('_base64_enoded_string_');
он предлагает:
INSERT INTO table .. VALUES(base64_decode('_base64_enoded_string_'));Соответственно в вашем случае хранинся - b64, в его - чистый текст.
Но, да, его вариант решает пробоему SQL-Inj ( по сути - проблему разбора SQL-запросов).
Хотя, ихмо, использование подстановок с один раз написанным и отлаженным экранированием работает не хуже.
>Но, да, его вариант решает пробоему SQL-Inj ( по сути - проблему
>разбора SQL-запросов).
>Хотя, ихмо, использование подстановок с один раз написанным и отлаженным экранированием работает
>не хуже.Практика показывает, что экранирование под давлением человеческого фактора совсем не работает, даже в Joomla криво экранируют и mod_security не помогает.
И правильно заплевали.
Ваше решение из разряда защитимся от XSS и для этого всё в базу будем ложить уже с заменой на HTML-мнемоники, тем самым портя данные. Это архитектурная ошибка может вам встать боком в самый неподходящий момент.
Предложение Камински интересно, но не более. Не особо много преимуществ по сравнению с параметризованными запросами, а если у вас используется нормальный ORM, то такой проблемы вообще нет.
Верно сказано.Чем эти методы лучше использования, скажем, PDO с параметрами и нормального эскейпера для вводимых пользователями данных? Хуже они тем, что усложнят запросы, раздуют размер передаваемых данных, а так же усложнят отладку. А передавать с вебсайты блоки данных, которые потом JavaScript будет декодировать и распихивать по тегами - вообще редкостное извращение. А если пользователям надо, скажем, запостить блок текста с жирным текстом и курсивом?
>И правильно заплевали.
>Ваше решение из разряда защитимся от XSS и для этого всё в
>базу будем ложить уже с заменой на HTML-мнемоники, тем самым портя
>данные. Это архитектурная ошибка может вам встать боком в самый неподходящий
>момент.Вы ошиблись. Я не от XSS защищал, а от SQL injection. Это разные вещи. Кроме того, моё приложение на момент разработки ни имело ни малейшего отношения к HTML.
И замена на HTML мнемоники не равноценна замене на base64, т.к. base64 не нарушает целостность данных.
>[оверквотинг удален]
>>Ваше решение из разряда защитимся от XSS и для этого всё в
>>базу будем ложить уже с заменой на HTML-мнемоники, тем самым портя
>>данные. Это архитектурная ошибка может вам встать боком в самый неподходящий
>>момент.
>
>Вы ошиблись. Я не от XSS защищал, а от SQL injection. Это
>разные вещи. Кроме того, моё приложение на момент разработки ни имело
>ни малейшего отношения к HTML.
>И замена на HTML мнемоники не равноценна замене на base64, т.к. base64
>не нарушает целостность данных.1. Я в курсе того, чем отличаются XSS от SQL-инъекции
2. Про замену на мнемоники..есть некоторые разработчики, которые сразу в базу ложат текст, в котором все HTML-спец.символы заменены на мнемоники. у вас аналогичное решение, только уже с base64. Просто что ваш, что методы Камински - по сути костыльные решения.
И во многом надуманные. Его аргумент, что программисты только под дулом пистолета могут использовать параметризированные запросы вообще не выдерживает критики.
На счет костыльного решения - 100%. Что моё, что Камински.
Я не приветствую решения, которые замедляют (читай увеличивают нагрузку на CPU) работу отдельных функций СУБД. Вот если создать работу со специндексами в самой СУБД (например, для полнотекстового поиска в кодировке base64 или подобной), которые будут работать не медленнее существующих - это уже будет не костыль, а фича!
Лол! Base64 в целях безопасности, такого еще не было.
Вы предлагали совсем другое. Глупо хранить в базе все строки в base64.
>Вы предлагали совсем другое. Глупо хранить в базе все строки в base64.Как по мне, похожее предложение. Да, другая проверка на соответствие base64.
На счёт глупо или нет - практика показала, что затруднен только полнотекстовый поиск (или частичный, как кому угодно). Всунуть мне левый запрос в принципе невозможно - я проверяю в приложении,которое работает с базой, на base64 соответствие.
Кроме того, я не предлагал ВСЕ текстовые строки хранить в base64. Только те, которые участвуют в запросах из общедоступных приложений или сторонних продуктов, чье качество кодирования проверить затруднительно.
>>Вы предлагали совсем другое. Глупо хранить в базе все строки в base64.
>
>Как по мне, похожее предложение. Да, другая проверка на соответствие base64.Читайте еще раз. Абсолютно не похожее.
Во всех нормальных библиотеках это происходит и так (псевдокод):$query = parse("select * from users where id = :users")
$query->bind('users', $users);
$query->execute();И в MySQL, и в Oracle такое есть.
Автор это объясняет тем, что ни один програмер не пишет параметризированные запросы, кроме как под дулом пистолета. Якобы это сложнее, чем его костыль.
Не исключено, что в некоторых случаях так и есть. Или например когда сервер достался от некрофилов с каким-нибудь php4.
Фигня :)Параметризованные запросы сильно ускоряют работу при использовании нормальных СУБД, даже безотносительно к безопасности. Кодеры, которые не используют таких запросов, должны лишаться ЗП в обязательном порядке! :)
К сожалению, пыхпых 5 не умеет их поддерживать, если используется mysql, а не mysqli :( Но это уже другая песня.
Зачем mysqli да, если есть выбор пиши под постгрес, не пожалеешь. =)
И автора не обижайте, уверен, что он пошутил, насчет "никто не пишет".
Раз уж пошла такая пьянка... Есть неочевидный фактор, который заставляет меня усомниться в справедливости Вашей зарплаты. ;) Время выполнения запроса к типичному веб-приложению - доли секунды. Если оно реализовано на скриптовых языках по стандартной схеме типа apache+mod_php5, то через эту долю секунды процесс умирает вместе со всеми объектами параметризированных запросов, и они будут создаваться заново при каждом новом запросе. Количество использований каждого из prepared statements (речь ведь идёт о них?) в таком приложении будет скорее всего равно 1. Более того, так и должно быть, мы ведь не делаем селекты в цикле, верно? :) Соответственно, те выгоды, о которых Вы говорите, проявляются лишь в приложениях, которые непрерывно висят в памяти и не собирают контекст на каждый чих, будь то java-сервлеты или скрипты+fastcgi. Я замерял, биндинг mysqli проигрывал примерно на 30% конкатенации+mysql_real_escape_string(), хотя эта цифра может служить для ориентировки.
>Раз уж пошла такая пьянка... Есть не очевидный фактор, который заставляет меня усомниться в справедливости Вашей зарплаты. ;)Ты написал тупость, которая даже в мена костыле MySQL уже не соответствует действительности ...
Простой вопрос на засыпку, что происходит (в нормальных DBMS) после того как парсер разобрал параметризованный запрос, но до того как ты забиндил значение и позвал экзекутор?
Подсказка: ну хорошо - позвал ты экзекутор, что происходит дальше?
Вот - вот, семь раз RTFM - один раз ... :)
Вообще написал он правильно - разница в скорости выполнения минимальна.
Вызов функций биндинга даже чуть подороже, чем склейка строки + эскейпинг. Вобщем мы от этого отказались еще года два назад, когда только написал для симплы драйвер PDO, сначала написал с биндингом параметров, потом поставил опцию раскрытия симплой - получилось быстрее.Разумеется это не относится к циклу одинаковых запросов, но это настолько редкая ситуация, что смысла нету.
Вы в корне не правы (или правы в некотором частном случае)!
может быть для MySQL это и правда, но приличные СУБД (в частности Oracle) _кешируют_ запросы после парсинга. в итоге запрос повторно разбирать не нужно!
собственно число запросов в приложении конечно и при достаточном обьеме кеша у СУБД это неплого ускоряет работу.
>Вы в корне не правы (или правы в некотором частном случае)!
>может быть для MySQL это и правда, но приличные СУБД (в частности
>Oracle) _кешируют_ запросы после парсинга. в итоге запрос повторно разбирать не
>нужно!
>собственно число запросов в приложении конечно и при достаточном обьеме кеша у
>СУБД это неплого ускоряет работу.Так ли в корне он неправ? Помимо времени на компиляцию запроса есть ещё фактор двойной передачи данных - запроса и параметров. Скорее всего, вычисление ключа кеша осуществляется на сервере, а значит текст запроса всё равно нужно сначала передать на сервер. Так что продолжать спорить считаю бессмысленным, и если у Вас есть под рукой Oracle с быстрым надёжным каналом до него, буду рад увидеть результаты тестов.
Я знаю, что правильно написал, потому что проверял это реальными тестами mysqli, а не просто занимался упражнениями в красноречии. :) Также я всегда готов выслушать обоснованные возражения и по-нормальному поспорить, чтобы докопаться до истины, но не вижу смысла отвечать анонимусам, которые готовы только гадить на голову коллег по цеху, но по существу вопроса ничего не пишут. :)
>Вот - вот, семь раз RTFM - один раз ... :)Семь раз RTFM, один раз rm -rf :D
Полная чушь, если нормально реализовано, то никто просто не захочет писать не параметризованные запросы, так как они сильно упрощают код.В PDO как раз реализовано не нормально - синтаксис многословный.
Посмотрите как реализовано тут - http://dklab.ru/lib/DbSimple/$db->select('select * from table where fname=? {AND id IN (?a)}', 'user', array(1,2,3));
После использования такого синтаксиса как раз писать по старому будешь только под дулом пистолета.
Вся прелесть параметризованных запросов как-то в миг рушится, когда параметром оказывается часть имени таблицы. Ещё хуже, когда перестраиваются фрагменты запроса и в нём появляются/исчезают вложенные подзапросы и уровни вложенности этих запросов.
Сходите по ссылке'select * from ?_table' - префикс - по сути самый часто используемый вариант
'select * from ?# where ...', 'tbl' - имя
Вложенные подзапросы тоже есть, плюс в новой версии на форуме есть плейсхолдер подзапроса, можно творить такое, что я уже не знаю что туда можно добавить.http://forum.dklab.ru/viewtopic.php?p=180253#180253
К сожалению либа была заброшена немного, но сейчас в составе фреймворка развивается
https://sourceforge.net/projects/quickfw/
>Сходите по ссылке
>'select * from ?_table' - префикс - по сути самый часто используемый вариантДык кто бы сомневался - творчеВство пехепешников - оно вообще вштыряет не по детски.
То что такими гениальными запросами ставится на колени любая субд на любом железе уже "не проблемма кодера" да? :)
Что именно чушь? Если СУБД не поддерживает параметризированные запросы, то никакой API их не сделает. Как вы собираетесь писать параметризированные запросы к какой-нибудь MSSQL 2k, или как вы будете делать аудит кода на php4, переписывать полностью на php5?ИМХО чушь это использовать на продакшне непонятные ноунэйм библиотеки. Вы проверяли, что эта DbSimple действительно делает параметризированные запросы? А вы уверены, что она так со всеми запросами будет делать? Или, что в ней нет многолетней дыры, которую просто некому заделывать, потому что никому не надо?
То что в API выглядит запросом с параметрами, к СУБД может идти обычной строкой.
Я ее дописывал, а не только проверял.
Что может - использует встроенные параметризации, что нет - раскрывает и сама экранирует.
В случае, если параметры не поддерживаются, то конечно идет обычной экранируемой строкой.
Почему-то в PDO нету подстановки в качестве параметров массивов, идентификаторов, и прочих полезных вещей.
>Я ее дописывал, а не только проверял.
>Что может - использует встроенные параметризации, что нет - раскрывает и сама
>экранирует.
>В случае, если параметры не поддерживаются, то конечно идет обычной экранируемой строкой.
>
>Почему-то в PDO нету подстановки в качестве параметров массивов, идентификаторов, и прочих
>полезных вещей.А вам не кажется, что использование "черного ящика", который то экранирует то параметоризирует, распускает разработчика, который начинает излишне доверять сторонней библиотеки, но по сути курит на бочке с порохом ? Я бы не стал доверять внешнему универсальному коду экранирования, например, дыры с недоэкранированием при передачи битого unicode классический пример, что и на старуху бывает проруха.
А вам не кажется, что придумывание своего велосипеда, который хоть и известен до каждого винтика, но как всегда получится с квадратными колесами (доказано огромным количеством примером - столько CMS/форумов/фреймворков приделают в качестве доступа к базе такую фигню, что за голову берешься), взяли бы хоть PDO, и то лучше было бы.Экранируется кстати стандартными функциями - mysql_real_escape в случае mysql, pdo::quote в случае PDO, и так далее.
>Экранируется кстати стандартными функциями - mysql_real_escape в случае mysql,Вот видите, вы сами подтвердили мою гипотезу о том, что не стоит доверять внешним универсальным решениям. Я как раз упоминал о хитрых методах обхода экранирование через многобайтовые кодировки, о которых разработчики разных функций проверки не догадывались.
http://secunia.com/advisories/20365/
"The vulnerability is caused due to an error within the server when parsing a query string that is escaped with the "mysql_real_escape_string()" function. This can potentially be exploited in an environment that uses multi-byte character encoding to bypass SQL injection escaping."
Вы только что доказали, что вы "Аналитик с лора"Тоесть вы предлагаете экранировать самому - в результате допустить еще неизвестно какие баги, но жутко бояться уже пофикшенного давным давно бага.
SQL injection vulnerability in MySQL 4.1.x before 4.1.20 and 5.0.x before 5.0.22
Аналитик, такой аналитик.
Я предлагаю не испытывать излишнего доверия к "черным ящикам", так как в этом лишнем звене могут быть дыры. Если пользователи "mysql_real_escape_string()" увидят появление узявимости, то пользователи вашего черного ящика могут догадаться о ней только по косвенным признакам или после аудита кода. И не факт, что дыру в "черном ящике" автор исправит на следующий день, она может годами висеть незамеченной.PS. Вы скатились до личных оскорблений, не имея аргументов для возражения. Посему считаю дискуссию законченной.
Понятно, позиция называется - пишем на ассемблере все.Вы сейчас несете чушь - использование стандартных функций там, где можно - лучше, чем писать свои, которые реализуют ту-же самую функциональность.
Если исправят баг в основной, то баг исправится и тут, а вот если бы был сделан велосипед, который предложили вы, то он как раз бы и висел бы годами не найденный.Излишнего доверия к "черным ящикам" никто не испытывает, более того код тут открыт, и даже пару багов было найдено и исправлено.
Стандартный функционал mysql_* функций совершенно не подходит, поэтому и была изначально написана эта библиотека, потом появился php5 с PDO, функциональность которого была лучше, но тоже не совсем устраивала, но для него был написан адаптер, который использует эту функциональность.
Вот если PDO или что-то еще разовьется до того уровня, чтобы предоставить аналогичную функциональность, то тогда эта библиотека будет не нужна, вот только когда это будет, и будет ли вообще :)
Оскорблений не было, это констатация факта :)
>Вы сейчас несете чушь - использование стандартных функций там, где можно -
>лучше, чем писать свои, которые реализуют ту-же самую функциональность.Стоп, это же именно вы предлагайте использовать левую нестандартную библиотеку вместо стандартных функций экранирования PHP.
>Если исправят баг в основной, то баг исправится и тут,Если автор левой библиотеки, которой пользуются 10 человек, не забросит свой проект. Посмотрите последние обновления безопасности в RHEL, там поправили дыры годичной давности,
как раз в библиотеках, подобных вашей.>Стандартный функционал mysql_* функций совершенно не подходит, поэтому и была изначально написана
>эта библиотека, потом появился php5 с PDO, функциональность которого была лучше,Вот и надо было продвигать идеи в mainstream, а не создавать левый проект, использование которого целесообразно только для людей, принимающих участие в его разработке.
Нет, я как раз предлагаю использовать стандартные функции - в случае mysql - mysql_real_escape_string, в случае PDO - PDO::escape, а вы тут ругаетесь на то что раз она бажная, то нужно написать свою обертку.>Вот и надо было продвигать идеи в mainstream, а не создавать левый проект
Вы пробовали что-то продвинуть в mainstream? У меня есть опыт - и патчи psi+ в psi очень медленно, и в taglib довольно долго патч в пакет добавляется.
А тут вы хотите изменить идеологию работы PDO - подумайте, сколько геморроя это доставит.
Насчет десятка человек - dklab.ru довольно известный сайт среди русских php разработчиков, довольно популярная библиотека.
>Вы пробовали что-то продвинуть в mainstream?Я пробовал принимать в mainstream :-)
Release Date 2006-06-02
Не вижу проблем писать код вида (псевдокод):
$conn->query("SELECT * FROM table WHERE fname='".$conn->quote($fname)."'";Меня ни разу не обламывает экранировать переменные. Хотя, тут больше приходятся полагаться на внимание разработчика. Но, неужели сложно экранировать ВСЕ переменные, если нет уверенности в разработчике? Просто принять это как договорённость при разаработке проекта. А за неэкранированные больно бить по гениталиям.
ИМХО, компактней, чем bind. Но о вкусах не спорят. ) Bind тоже катит. )
вот тут-то как раз собака и порылась - если использовать биндинг то параметры всегда экранированы, совсем без участия разработчика, а если полагаться на экранирование "по ходу", то разработчик постоянно должен об этом думать (будто ему больше заняться нечем). В проекте с тысячами запросов это просто нереально, будь программисты хоть абсолютные педанты, кто угодно может забыть или просмотреть что-то. И случается это часто как раз в таких местах где визуально не сразу и заметишь, так что полагаться на то что другие коллеги обнаружат тоже нельзя. Поэтому такие дыры лучше ищутся автоматизированно, но тогда это уже аудит называется и стоит отдельно. Или жить с риском что кто-нибудь сделает это за тебя, но только тогда этот кто-то может отверстием сразу и попользоваться. А оно надо, весь этот гемморой?
Да, все правильно.
По сути этоиу правилу удовлетворяет PDO, а симпла, про которую я писал выше - это доведенное до нормального интерфейса PDO.
Вот в Постгрес есть такая тема, можно задавать любые ограничители типа $something$
тоесть писать запросы типа select * from users where name=$pipiska$Вася$pipiska$;В похапе во входящих на всякий случай заменяем $pipiska$ на SpipiskaS и вставляем. Чем не метод?
Это всё конечно интересно, да вот только ПМСМ нормальные программеры итак заботятся о безопасности и проверяют входные данные. Кто будет пользоваться этим методом, вас много наберётся?
>Это всё конечно интересно, да вот только ПМСМ нормальные программеры итак заботятся
>о безопасности и проверяют входные данные. Кто будет пользоваться этим методом,
>вас много наберётся?Только нормальный программеров раз-два и обчелся, или их код обязательно будет разбавлен кодом "ненормальных". По вашему Drupal, Typo3, phpbb, Joomla и почти любой другой крупный проект на PHP пишется спустя рукава ? Тем не менее в них регулярно находят SQL Injection и баги, связанные с отсутствием экранирования/проверки пользовательского ввода. Казалось бы получил одну такую дыру, провел аудит кода и живи спокойно, но грабли продолжают лежать, а разработчики продолжают на них наступать. Так что не все так просто как кажется, нужна именно панацея, подобная описанной в новости. Дополнительные решения типа mod_security часто остаются бесполезными или в них самих дыры всплывают.
>По вашему Drupal, Typo3, phpbb, Joomla и почти любой
>другой крупный проект на PHP пишется спустя рукава ? Тем не
>менее в них регулярно находят SQL Injection и баги, связанные с
>отсутствием экранирования/проверки пользовательского ввода.Значит пишут спустя рукава. Или это PHP виноват? :)
>>По вашему Drupal, Typo3, phpbb, Joomla и почти любой
>>другой крупный проект на PHP пишется спустя рукава ? Тем не
>>менее в них регулярно находят SQL Injection и баги, связанные с
>>отсутствием экранирования/проверки пользовательского ввода.
>
>Значит пишут спустя рукава. Или это PHP виноват? :)А кто мешает писать спустя рукава с использованием именно этого метода? :) Разве мало мест где багов и дыр можно навешать, кроме этой, которую заткнете?
Вы считаете что у друпала или у джумлы хороший код?
Блин, да достаточно посмотреть на их либы для работы с базами данных и уже понятно какие там "специалисты" сидят.
Джумла вообще такое чувство что на коленке собрана, имел счастье копаться в ее коде...
>Вы считаете что у друпала или у джумлы хороший код?
>Блин, да достаточно посмотреть на их либы для работы с базами данных
>и уже понятно какие там "специалисты" сидят.
>Джумла вообще такое чувство что на коленке собрана, имел счастье копаться в
>ее коде...Давайте пойдем от обратного, можете привести пример качественного PHP-проекта, который более-менее распространен в сети ?
Ну например ZendFramework - довольно хороший код.
Неплохой в кохане, правда не особо много видел, сужу только по той части, которую видел.
Вообще по части библиотеки доступа к базе данных - если при запросе к базе данных есть код вида$var = $db->escape($var);
$db->query("..$var..");(тоесть можно передать неэкранированные данные просто забыв их экранировать)
то это индикатор, что библиотека доступа к базе данных...
Безумие какое-то... workaround для безграмотности.BTW - параметризованные запросы не просто делают код читабельным и избавляют от проблемы sql injection, но в разы (иногда в десятки раз) улучшают производительность запросов (парсинг sql, построение плана запроса...).
"о сколько нам открытий чудных готовит просвященья дух...." ((c) А.Пушкин)
если учесть сколько народу пишет для mysql, то там нативного биндинга нет и изза эмуляции производительность всётаки несколько падает, хотя и незначительно в сравнении с временем выполлнения запроса. А в остальнов полностью согласен, в плане безопасности ничего разумнее параметризированных запросов для sql пока не изобрели, да врядли изобретут. Да и автор статьи по сути предложил то-же самое, только таким вот странным способом.
>BTW - параметризованные запросы не просто делают код читабельным и избавляют от
>проблемы sql injection, но в разы (иногда в десятки раз) улучшают
>производительность запросов (парсинг sql, построение плана запроса...).
>
>"о сколько нам открытий чудных готовит просвященья дух...." ((c) А.Пушкин)Иногда да, иногда нет. :) См. комментарий #61.
> Иногда да, иногда нет. :) См. комментарий #61"нет", на мой взгляд, справедливо для очень узкого круга задач, обычно очень простых, для которых, действительно, не важна ни производительнсоть (и безопасность) ни здравый смысл.
Но задача в пределах request-а обратиться одинаковым запросом минимум дважды - типовая и характерна для сколь нибудь существенных приложений, даже не очень сложных.
ЗЫ: drupal, например, очень активно переходят на параметризованные запросы.
Видимо, стало стыдно :)
:) Я как раз говорил, что в типичном скриптовом веб-приложении скорее всего будет "нет", и обращение к одному sql-запросу будет единожды. Потому что типичный http-запрос должен отработать на сервере по принципу "сделать как можно меньше и как можно быстрее умереть". Другое дело, что производительности можно достичь другими способами, а вот безопасность никогда не бывает лишней.
ИМХО автор просто подошёл к проблеме интересным образом. Я не говорю, что он решил проблему в корне или что он изобрёл что-то гениальное. Просто действительно интересный вариант. И всё. Не думаю, что этот способ начнёт массово применяться в продакшене ;)) тем не менее значение его больше "а ещё это можно сделать так...""...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
Верно, решение интересное. Возможно, что в каких-то других областях программирования его даже применят с пользой. Но как серьезное "улучшение" защиты от SQL инжекшенов это рассматривать нельзя.
На самом деле действительно гениально и просто.Я бы, по крайней мере, до такого точно не додумался бы, поскольку пользуюсь prepare/bind/execute.
Интересно, знает ли сам автор про биндинг переменных.
совсем крыша поехала, вставлять eval и рассуждать о безопасности? Кроме того эта байда в такой форме работать не будет, надо бы на b() ещё и сами параметры передать.
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 для пхп - это отказ от пхп.
Последний вывод у вас странный.Есть нормальные проекты, просто блин никто в здравом уме и доброй памяти не будет вам в открытый доступ выкладывать хороший код - по крайне мере очень редко.
А если пишется в соответствии с идеологией олпенсорса - каждый прикрутит маленькую фигню, то и получается такой отстой как джумла или друпал.Фраза "даже друпал и жумла" некорректна - слово даже тут нельзя применять, это два примера феерически раскрученного отстоя.
А язык хороший, не надо, просто на нем просто сделать криво, но это не значит что так нужно делать.
>[оверквотинг удален]
>не будет вам в открытый доступ выкладывать хороший код - по
>крайне мере очень редко.
>А если пишется в соответствии с идеологией олпенсорса - каждый прикрутит маленькую
>фигню, то и получается такой отстой как джумла или друпал.
>
>Фраза "даже друпал и жумла" некорректна - слово даже тут нельзя применять,
>это два примера феерически раскрученного отстоя.
>
>А язык хороший, не надо, просто на нем просто сделать криво, но
>это не значит что так нужно делать.Зря Вы так про опенсорс, просто бывают разные модели разработки. Бывает например разработка преимущественно силами комьюнити, там действительно так и получается, а бывает часто что фирма преимущественно или полностью своими силами разрабатывает, но выкладывает в открытый доступ потому что это сегодня выгодно во многих отношениях. Или даже некоммерческие проекты, но где одна более-менее постоянная комманда и один лидер тон задаёт. Загляните в код sugarcrm, рекомендую :)
Я так не про олпенсорс вообще, а про разработку силами комьюнити.
Вот если разрабатывает одна фирма или команда получается как раз нормально.
А когда приходит "комьюнити", то получается фигня.
как-то довелось делать аудит для чужого проекта с тремя тысячами запросами по коду, чуть не каждый третий дырявый. Так вот главный программер с этой фирмочки уверял что у него magic_quotes_gpc включен и всё защищает. Про такие вещи как "select name from user where id=$id" он не подумал, что туда можно банально подзапрос в скобках вставить :)
>4. Выше было замечено, что даже друпал и жумла пишутся "спустя рукава". Ну а что можно написать на пхп не спустя рукава? Какой нормальный программист будет использовать эту поделку, в которой какие-то переменные конфига меняют всю суть "языка", синтаксис понадёрган из 30 разных языков и то возможности, которые были изначально в других давно существующих языках, появляются только в версии 5.3, а ещё (при программистской лени) нужно зачем-то везде ставить эти $, ->, array() и прочие идиотские излишества. Код на пхп убог по сути пхп. И единственное универсальное средство против sql-injection для пхп - это отказ от пхп.А что бы вместо пхп предпочли вы?
В то время, как такие, как Вы, орут об убогости пхп на форумах, нормальные разработчики зарабатывают деньги на написанных на пхп проектах :-)"Ах, Моська, знать, она сильна, что лает на слона..."
Ну, и ещё раз о главном (хоть, это возможно просто пример):
За $conn->query("...fname=$fname...") надо больно бить по йайцам. Хотя бы, но не ограничиваясь (!) $conn->query("...where fname=".$fname."..."). Так переменную хоть заметней.
на самом деле, это защита от неопытного/не очень грамотного кодера. Для больших проектов подойдёт.Хорошо бы без eval'ов и чтобы (без wrapper'а не срабатывало|wrapper применялся неявно). Но, в таком случае приходим как раз к bind'у.
Короче - проект - не панацея. Тем более с eval'ами. )
ха-ха-ха!За второй вариант по яйцам бить нужно так-же больно.
Странно, что устроили такой холивар на пустом месте. Никто не заставляет вас использовать это в продакшене. Во время разработки напишите функцию MyEscape, которая в дебаге будет переводить аргумент в Base64, а в релизе вызывать функцию ескейпа. В базе данных разработчика повесить на вставку, обновление, удаление функцию расшифровки из base64. В результате вы на этапе разработки вы нигде не забудете делать экранирование.
не смешно
Способ конечно неплохой, но не всегда удобный.
Кроме того, есть ещё такая вещь как "prepared statement".
Я хотел сказать: очень старый баян :)
Проблема в том, что base64 - по природе своей костыль. Если подумать, "экранировка", в общем-то, тоже. Надо копать в какую-то другую сторону, imho, отделять мух от котлет более радикально.
base64() ничем не лучше встроенных в БД методов квотирования, а минусы есть -- декодирование для БД не родное. Здесь Дэн облажался.