В настоящее время я использую расширение mysqli php.
Традиционно я использовал mysqli_real_escape_string, чтобы избежать ввода пользователем. Однако я рассматриваю возможность изменения кода (надеюсь, как можно меньше шагов) для использования подготовленных операторов.
Я хочу быть ясным на этом – если я использую подготовленные инструкции для привязки всех моих переменных, могу ли я быть уверенным, что SQL-инъекция невозможна? (И полностью отказаться от mysqli_real_escape_string?)
благодаря
Если вы правильно привязываете все свои переменные, вы можете значительно снизить риск внедрения SQL. По-прежнему можно получить SQL-инъекцию, если вы динамически создаете SQL:
'SELECT * FROM ' . $tablename . ' WHERE id = ?'
Но если вы избежите подобных вещей, вряд ли у вас будут проблемы.
Говоря о безопасности, нет никакой разницы между обоими методами, если вы правильно привязываете или форматируете переменные.
Связывание просто проще, потому что его можно использовать только для любого случая, в то время как экранирование не может (поэтому вам нужно наложить некоторые переменные вместо escape-кавычки).
Кроме того, имейте в виду, что никакие привязки и экранирование не могут сделать идентификатор безопасным. Итак, если вам нужно использовать имя поля или оператора в вашем запросе, вы должны использовать значение, жестко закодированное в вашем скрипте.
Вот мой высокоуровневый взгляд на эту тему.
При использовании динамических строк 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
ошибкой mysqli_real_escape_string
, я полагаю, что всегда есть вероятность, что обнаруженная (или вновь созданная) ошибка будет казаться невозможной, возможно.