Почему использование подготовленного оператора mysql более безопасно, чем использование общих функций escape?

в другом вопросе есть комментарий, который говорит следующее:

"когда дело доходит до запросов к базе данных , всегда старайтесь использовать готовые параметризованные запросы. Mysqli и Библиотеки PDO поддерживают это. Это бесконечно безопаснее, чем использование escaping такие функции, как использования mysql_real_escape_string."

источник

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

7 ответов


важным моментом, который я думаю, что люди здесь отсутствуют, является то, что с базой данных, которая поддерживает параметризованные запросы, нет "побега", о котором нужно беспокоиться. Компонент database engine не объединяет связанные переменные в оператор SQL, а затем анализирует все это; связанные переменные хранятся отдельно и никогда не анализируются как общий оператор SQL.

вот откуда берутся безопасность и скорость. Компонент database engine знает, что заполнитель содержит только данные, поэтому никогда не анализировался как полный оператор SQL. Ускорение происходит, когда вы готовите оператор один раз, а затем выполняете его много раз; канонический пример-вставка нескольких записей в одну таблицу. В этом случае компонент database engine должен анализировать, оптимизировать и т. д. только один раз.

теперь, один gotcha с библиотеками абстракции базы данных. Иногда они подделывают его, просто вставляя связанные переменные в инструкцию SQL с правильным экранированием. Тем не менее, это лучше, чем делать это себе.


во-первых, вы оставляете побег опасных персонажей в базе данных, что намного безопаснее, чем вы, человек.

... он не забудет убежать или пропустить какие-либо специальные символы, которые могут быть использованы для ввода вредоносного SQL. Не говоря уже о том, что вы можете получить повышение производительности для загрузки!


Я не очень разбираюсь в безопасности, но вот объяснение, которое я надеюсь, поможет вам:

предположим, у вас есть утверждение типа:

выберите [integer] из mydb

притворитесь, что при его подготовке оператор компилируется до байтов в нашей воображаемой реализации sql.

           01                  00 00                  23
Opcode for select          Prepared bytes      number of "mydb"
                          for your integer

теперь, когда вы выполняете, вы вставите номер в пространство, зарезервированное для вашего подготовленного оператора.

сравните его, если вы просто используете escape, вы могли бы вставить там столько тарабарщины и, возможно, вызвать переполнение памяти или какую-то команду Bizzare sql, которую они забыли избежать.


потому что с подготовленными заявлениями, вы не можете забыть, чтобы избежать содержание. Таким образом, нет никакого способа ввести неуверенность.

mysql_real_escape_string так же безопасен, как подготовленные операторы, если вы помните использовать mysql_real_escape_string каждый раз, когда вы вызываете mysql_query, но это легко забыть.


функция небезопасна из-за этого эксплойта http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string. Именно поэтому предпочтение отдается подготовленным заявлениям, а также повышению производительности.


подготовленные заявления решения фундаментальная проблема безопасности применения что простые данные санитарии не получается полное разделение данных и инструкции. Когда они путаются, результатом становится неуверенность. Это верно для SQL-инъекции, а также переполнения буфера.

(есть и другие способы, чтобы быть неуверенным.)


в лучшем случае, это может быть и не так, но это, по крайней мере, одинаково безопасно; и зачем рисковать?