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

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

«Когда дело доходит до запросов к базе данных, всегда старайтесь использовать подготовленные параметризованные запросы. Библиотеки mysqli и PDO поддерживают это. Это намного безопаснее, чем использование экранирующих функций, таких как mysql_real_escape_string».

Источник

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


person João Josézinho    schedule 09.04.2009    source источник


Ответы (7)


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

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

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

person MadCoder    schedule 09.04.2009
comment
Так это быстрее, но безопасность такая же? Я имею в виду, что вы не можете быть в большей безопасности, чем в полной безопасности. Я также хотел бы некоторые доказательства теории скорости. - person Jonas Äppelgran; 24.09.2013

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

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

person alex    schedule 09.04.2009
comment
Но как база данных узнает разницу между тем, что опасно, и тем, что я действительно хочу сделать? - person João Josézinho; 09.04.2009
comment
Что ж, он знает, какие символы являются злыми, поэтому он должен добавлять escape-символ '\' в MySQL перед злым символом. Это по-прежнему выполняет запрос как есть, но не учитывает никаких специальных символов, которые появляются в привязке. - person alex; 09.04.2009
comment
Также обратите внимание, что вы указываете «привязки» отдельно (не объединяя их в запросе) и просто вставляете заполнители в запрос туда, где они должны отображаться. База данных (я думаю, может быть, PDO делает это?) Затем экранирует символы внутри привязок. - person alex; 09.04.2009
comment
Теперь я понял. Большое спасибо за вашу помощь: P - person João Josézinho; 09.04.2009

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

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

выберите [целое число] из mydb

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

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

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

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

person Unknown    schedule 09.04.2009

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

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

person Martin Tilsted    schedule 09.04.2009

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

person Bhushan Bhangale    schedule 09.04.2009
comment
Я считаю, что если я правильно читаю этот связанный блог, у него проблема с небезопасностью addlashes, а не с mysql_real_escape_string. В конце он говорит, что последний вариант является допустимым, если люди не забывают это сделать, но люди склонны забывать вызывать его. Использование подготовленных операторов помогает решить эту проблему с памятью. - person Carvell Fenton; 22.06.2012
comment
Это тоже интересная ссылка, которая указывает на потенциальную проблему с mysql_real_escape_string, хотя и неясную: ilia.ws/archives/ - person Carvell Fenton; 22.06.2012

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

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

person Scott Arciszewski    schedule 09.12.2015

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

person dkretz    schedule 09.04.2009