Я в настоящее время использую mysqli php расширение.
Традиционно я использовал mysqli_real_escape_string для выхода из ввода данных пользователем. Однако я смотрю на обмен кода (надо надеяться, на как можно меньшем количестве шагов) для использования подготовленных операторов.
Я хочу быть ясным на этом - если я использую подготовленные операторы для привязки всех моих переменных, я могу быть уверен, что внедрение SQL невозможно? (И распределите полностью с mysqli_real_escape_string?)
Спасибо
Если вы правильно привяжете все свои переменные, вы можете значительно снизить риск внедрения SQL. По-прежнему возможно получить SQL-инъекцию, если вы создаете SQL динамически, например:
'SELECT * FROM ' . $tablename . ' WHERE id = ?'
Но если вы избегаете подобных вещей, вряд ли у вас возникнут проблемы.
Говоря о безопасности, нет никакой разницы между обоими методами, если вы правильно связываете или форматируете свои переменные.
Просто связывание проще, потому что его можно использовать для любого случая, а экранирование - нет (поэтому некоторые переменные приходится приводить вместо экранирования/кавычек).
Кроме того, имейте в виду, что ни связывание, ни экранирование не могут сделать идентификатор безопасным. Поэтому, если вам нужно использовать имя поля или оператор в запросе, вы должны использовать значение, жестко закодированное в вашем скрипте.
Вот мой высокоуровневый взгляд на эту тему.
При использовании динамических строк SQL вы полагаетесь на то, что функция экранирования работает правильно. К сожалению, это не всегда так, как видно из этого (по общему признанию, старого) примера:
http://dev.mysql.com/doc/refman/5.0/en/news-5-0-22.html
После того как значения ваших данных были экранированы, строка SQL должна быть разобрана и скомпилирована сервером базы данных. Если функция экранирования не выполнила свою работу должным образом, или была обнаружена новая хитрая атака SQL-инъекции, существует вероятность того, что сервер примет данные за SQL-выражения.
Если вы используете подготовленные операторы с параметрами, то сначала оператор разбирается и компилируется. Значения данных объединяются с компилированным оператором при его выполнении. Это отделяет логику SQL от значений данных - возможность спутать эти два понятия не должна возникнуть никогда.
Итак, да, вы можете обойтись без mysqli_real_escape_string
, но я бы не стал заходить так далеко, чтобы утверждать, что использование подготовленных операторов с параметрами делает SQL-инъекции невозможными. Это значительно усложняет задачу, но, как и в случае с ошибкой mysqli_real_escape_string
, я полагаю, всегда есть шанс, что еще не обнаруженная (или вновь созданная) ошибка сделает, казалось бы, невозможное возможным.