Как защитить себя от внедрения SQL при использовании подготовленных операторов / процедур хранения в PHP? - PullRequest
2 голосов
/ 30 июня 2011

Я смотрел, как лучше всего защитить от SQL-инъекций в PHP / mysql не только использование реального выхода mysqli / mysql с момента прочтения этого Достаточно ли mysql_real_escape_string для Anti SQL Injection?1004 * Я видел эту очень хорошую ветку Как я могу предотвратить SQL-инъекцию в PHP?

Я использую много MS SQL-сервера на настольных / внутренних инструментах, мы всегда писалихранимые процедуры для защиты от этого, поэтому я прочитал эквивалент в PHP / mysql, используя PDO http://php.net/manual/en/pdo.prepared-statements.php

В приведенном выше есть строка:

Параметры для подготовленных операторовне нужно цитировать;водитель автоматически обрабатывает это.Если приложение использует исключительно подготовленные операторы, разработчик может быть уверен, что SQL-инъекция не произойдет (однако, если другие части запроса создаются с неэкранированным вводом, SQL-инъекция все еще возможна).

Меня убеждают, что PDO защищает от атак SQL-инъекций, поэтому кто-нибудь может предоставить экземпляр, где PDO недостаточно с точки зрения безопасности?

Ответы [ 2 ]

3 голосов
/ 30 июня 2011

Вы все еще можете получать инъекции SQL из хранимых процедур, которые внутренне используют синтаксис PREPARE (в MySQL) для создания динамических операторов SQL.

Это нужно делать с особой осторожностью, используя QUOTE () по мере необходимости.

В идеале нам не нужно использовать PREPARE в хранимых подпрограммах, но в некоторых случаях этого становится очень трудно избежать:

  • До MySQL 5.5 предложение LIMIT не могло использоватьнепостоянные значения.
  • Списки, используемые в предложении IN (), не могут быть (разумно) параметризованы, поэтому вам необходимо использовать динамический SQL, если этот шаблон используется
  • Иногда желательно использоватьдинамически генерируемые предложения ORDER BY.

и т. д.

В случае, когда необходимо использовать PREPARE, я бы порекомендовал в порядке предпочтения:

  • Если что-то имеет тип INT (и т. Д.), Оно не подвержено внедрению SQL, и вы можете поместить значение в запрос без проблем (например, для LIMIT)
  • Строковые значения cбыть помещенным в @variable перед EXECUTE или переданным в предложение EXECUTE
  • Необходимо проверить список значений (например, для IN ()).
  • Наконец,QUOTE () может использоваться для цитирования строковых значений, что может быть полезно в некоторых случаях
1 голос
/ 30 июня 2011

Решающую роль играет не используемая вами структура (хранимые процедуры, подготовленные операторы и т. Д.), А то, собираетесь ли вы в любой момент объединять SQL вместе, используя непроверенный пользовательский ввод .Например, вы можете выполнить динамический SQL из хранимой процедуры, и в этом случае опасность все еще существует.

Самый простой способ (с точки зрения предотвращения инъекций) - использовать SP или PS со связанными-in переменные: их не нужно проверять, так как они будут распознаны как значения, входящие в предопределенный заполнитель.

...