Я не очень знаком с PDO, но есть различие между «подготовленными утверждениями» и экранированными строками. Экранирование - это примерно удаление запрещенных символьных строк из запроса, но подготовленные операторы примерно сообщают базе данных, какой тип запроса ожидать .
Запрос состоит из нескольких частей
Подумайте об этом так: когда вы отправляете запрос в базу данных, вы говорите ему несколько разных вещей. Например, одна вещь: «Я хочу, чтобы вы сделали выбор». Другим может быть «ограничить его строками, ГДЕ имя пользователя является следующим значением.»
Если вы создадите запрос в виде строки и передадите его в базу данных, он не узнает ни о одной из частей, пока не получит завершенную строку. Вы можете сделать это:
'SELECT * FROM transactions WHERE username=$username'
Когда он получает эту строку, он должен проанализировать ее и решить, "это SELECT
с WHERE
".
Смешивание деталей
Предположим, злоумышленник вводит свое имя пользователя как billysmith OR 1=1
. Если вы не будете осторожны, вы можете поместить это в строку, что приведет к:
'SELECT * FROM transactions WHERE username=billysmith OR 1=1'
... что вернет всех транзакций для всех пользователей , потому что 1 всегда равно 1. Ой, вы взломаны!
Видите, что случилось? База данных не знала, какие части ожидать в вашем запросе , поэтому она просто проанализировала строку. Не было удивительно, что WHERE
имел OR
с двумя условиями, которые могли бы его удовлетворить.
Сохранение деталей прямыми
Если бы он только знал , что ожидать , а именно SELECT
, у которого WHERE
было только одно условие, злоумышленник не смог бы его обмануть.
С готовым утверждением вы можете дать ему правильное ожидание. Вы можете сказать базе данных: «Я собираюсь отправить вам SELECT
, и она будет ограничена строками WHERE username =
строкой, которую я собираюсь вам дать. Вот и все - других частей нет запрос. Вы готовы? Хорошо, вот строка для сравнения с именем пользователя. "
При таком ожидании база данных не будет одурачена: она будет возвращать только те строки, в которых столбец username
содержит фактическую строку 'billysmith OR 1 = 1.' Если ни у кого нет этого имени пользователя, оно ничего не вернет.
Другие преимущества подготовленных заявлений
В дополнение к преимуществам безопасности подготовленные операторы имеют несколько преимуществ по скорости:
- Их можно повторно использовать с различными параметрами, что должно быть быстрее, чем создание нового запроса с нуля, потому что база данных уже знает в основном то, что вы собираетесь запросить. Он уже создал свой «план запроса».
- Некоторые базы данных (я думаю, что Postgres - одна) начнут составлять план запроса, как только они получат подготовленное утверждение - прежде чем вы фактически отправите параметры для использования с ним. Таким образом, вы можете увидеть ускорение даже при первом запросе.
Для другого объяснения см. Ответ Тео здесь .