Имеет ли смысл фильтровать пользовательский ввод для предупреждения SQL-инъекций?
Имеет ли смысл фильтровать пользовательский ввод для предупреждения SQL-инъекций?
Пишу небольшой фреймворк, возник вопрос (выше).
Сейчас немного опишу архитектуру: MVC, есть фронт контроллер (больше ничего не надо).
Написав router задумался о анализе uri и параметров запроса, а так же куков и прочего на предмет SQL-инъекций.
Стоит ли нагружать этим функционалом роутер?
Зачем? чтобы уже при попытке "ввода инъекции" уже ничего не запускать и не выполнять (роутер сразу вызовет шаблон 404 и в админке в логах появиться алерт).
P.S>
prepared statements - да, разумеется, будет обертка PDO с подготовленными выражениями.
Всякие идеи о подобной "фильтрации" следует выкинуть навсегда из головы.
Апдейт.
Ну вот, учитывая PS, мы получаем, что первый вопрос ("для предупреждения инъекций") уже не имеет смысла. остается "алерт в админке". поверь мне - твои розовые фантазии о работе сайтов не имеют ничего общего с действительностью. Малолетние придурки бомбардируют сайты на предмет тупых уязвимостей постоянно. Один набор шаблонов поиска phpmyadmin состоит из сотни паттернов. Твой "алерт" на посещаемом сайте будет верещать постоянно. И без МАЛЕЙШЕГО смысла.
FanatPHP: Ну он тогда задан криво... речь шла об предупреждении атак, а не о средстве защиты. + основная идея все же при любом "бомблении" сайта, ну вообще ничего не делать. Вообщем то пока я понимаю, что да Вы правы...
не понял, что такое "предупреждение атак" в твоем понимании. Но в любом случае, все атаки ты не предупредишь, а вот честным пользователям будешь мешать. Поэтому такая проверка неприемлема.
FanatPHP: Скорее всего да буду мешать... Но вообщем-то фреймворк мой больше для самообучения (что естественно), и заточен он под интернет-магазин. Он вообщем исключает постинг какого-либо кода от "честных пользователей". А так например вести учет работы "продажников" внутри компании, что так же постинга кода не предполагает.
Tomass Tumass: понимаю как внедрение кода, который исполнится уже после вывода из БД... Необязательно данные из БД будут подставлять опять в мои prepared statements. Собственно, прокрутить все варианты в голове мне мозгов не хватает, поэтому нужен эксперимент. Ибо каким-то чудом файлы на сервере появляются... через них нагружают БД и т.д. А все эти примеры на 5-ти пальцах в статьях - ерунда для объяснения чайникам (вроде меня) что это вообще такое. Так посмотришь на взломанный PHPadmin, shopscript... и понимаешь, что тему еще курить очень долго.
MGriboedoff: Томас очень правильно пишет: если prepared statements используются везде. Если кто-то не делает правильную защиту от инъекций, то это он виноват. И лечить надо не следствие, а причину. То есть ИСКЛЮЧИТЬ случаи, когда данные не обязательно будут подставлять в prepared statements.
Нужно просто соответствующим образом экранировать данные. Или использовать prepared_statements, которые сами обо всем позаботятся.
> чтобы уже при попытке "ввода инъекции" уже ничего не запускать и не выполнять
А если вдруг пользователь захочет в блоке о вашем фреймворке опубликовать статью об инъекциях с примерами?
надо убрать слово экранировать. во-первых, оно не имеет отношения к инъекциям, а во-вторых, единственным способом помещения переменной в запрос, должен быть prepared statement
Идея пресечь все в самом начале, вне зависимости от того, что и как реализовано в других слоях. Хочется проверку в точке входа (заманчиво, но мало вероятно). Так как все остальные слои "очищают" данные по мере необходимости, такая проверка вроде как избыточна. Часть запросов отсеять на входе, чтобы не посылать никаких данных и никаких запросов в n% случаях. Вопрос смысла как разв в N% и ресурсоемкости это самой "подсветки".
На край можно собрать статическую информацию о попытках взлома)) А так вообще смысла нет.. так 100% гарантии нет и вообщем если в других слоях "наколбасят" проверка в точке входа не спасет.
"в начале" пресечь невозможно. Это самое главное, что тебе надо понять (и что ты, судя по всему, уже начинаешь понимать). Логика тут простая: "черный список" (который ты предлагаешь), НИКОГДА не является 100% гарантией защиты. Гарантией является толкьо корректное форматирование данных. Но на входе форматировать данные для SQL попросту нельзя. Форматировать же данные надо только перед самым исполнением запроса. А это обеспечивают только подготовленные выражения
FanatPHP: Prepared_statements не единственный способ. Никто не мешает использовать специализированные функции именно для экранирования (те же mysqli_real_escape($str) и им подобные) и не забывать о типах подставляемых данных (а помнить о них нужно и при prepared_statements).
Александр Боровиков: Ну вот тут я не согласен, подготовленные выражения и отсутствие какой-либо возможности добавить оператор в запрос ну более, чем достаточна.
Идея предупреждения атак в поиске не каких то символов или слов, а в фильтрации их сочетаний.
FanatPHP: Ну да 100% защиты так не добиться - факт. Ну или это будет какая-нибудь самообучаемая система, создание которой бесконечно долго и не имеет смысла (шутка))))
Ну да на точке вход я не знаю, что это за данные и куда они пойдут... а фильтр универсальный очень как-то сложно... выглядит как безумные регулярки, которые скорее нагрузят приложение чем разгрузят...
Ну в качестве "бесценного опыта" проведу пару экспериментов))
Александр Боровиков: ё-моё. 21 век, второй десяток. И до сих пор приходится несчастным хомячкам объяснять, что mysqli_real_escape($str) и им подобные не имеют отношения к какой бы то ни было защите.
Александр Боровиков: Александр Боровиков: FanatPHP имеет ввиду, что есть два решения в области передачи данных в БД. 1)подготовленные выражения + отсутствие возможности со стороны пользователя вставить отсебятину вместо оператора. При этом использование mysqli_real_escape() смысла не имеет, так как насколько я знаю спец. символы и так экранируются - избыточное решение уж совсем.
Кроме того, решении с mysqli_real_escape дыряво, и обходится через взлом кодировкой. Сам не проверял, только слышал и есть пару скриптов, которые остались от взлома сайта (еще не изучал).
Вообще мало что сам проверял, оттуда и вопросы... А все что программировал до этого использовалось как "сферический конь в вакууме", которого никто ломать не будет. Поэтому вопрос безопасности для меня сейчас актуален для изучения...
MGriboedoff: читай внимательнее мои реплики. mysqli_real_escape не имеет отношения к безопасности. Вообще. И дело не в дурацкой страшилке про кодировку (во-первых, если делать не кривыми руками, то не будет никакого взлома через кодировку. Во-вторых, если даже делать так, как делают такие боровиковы - то тоже проблемы не будет, поскольку ни в одной из русских кодировок этой проблемы все равно нет). Дело в в том, что эта функция Никакого. Отношения. К. Защите. Не. Имеет.
FanatPHP: Ну прямо что она "защитник" и это есть ее функция... это конечно нет. Функция экранирует спец. символы, что вообщем можно использовать и для защиты, но ни как единственную защитную функцию, а как одну из нескольких (я так понимаю господина Боровикова).
MGriboedoff: НЕЛЬЗЯ. Ты не понимаешь, что такое спецсимволы, но туда же - "можно использовать и для защиты". Не позорься. Ты не представляешь, какую чушь сейчас написал.
Экранировать надо ограничители строки. Это очевидно же - если у нас есть гораничитель, то внутри его надо экранировать, чтобы строка не прервалась прежде времени.
Вообщем почитал, поглядел, данные нужно фильтровать поэтапно, частями именно там где используешь.
Например, нет смысла фильтровать запрос, если не правильно указан контроллер в URL - пустая трата времени.
А функции анализа данных должны быть под конкретный типа данных, многие функции уже есть в PHP (например проверка на валидность e-mailа и т.д).