Задать вопрос

Как именно плейсхолдеры (подготовленные выражения) защищают от sql-инъекций?

Доброго дня.
Собственно, сабж. Прочитав описание подготовленных выражений из документации на php.net, где ничего не говорится о самой реализации, я порой даже опасаюсь использовать подготовленные запросы: мне приходится верить на слово авторитетным разработчикам, авторам статей на хабре и той же документации (в таких случаях я составляю "белые списки с именами полей и возможными значениями, что порой существенно усложняет реализацию). Очевидно, что данный подход при написании запросов - едва ли не единственно верный, сам уже давно использую лишь его, однако полного понимания до сих пор нет. Что именно происходит с переданными в ту же PDO параметрами там, внутри, в момент подготовки и выполнения запроса?

Заранее спасибо!
  • Вопрос задан
  • 4773 просмотра
Подписаться 10 Оценить Комментировать
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 2
Подготовленные выражения защищают от SQL-инъекций тем, что отделяют синтаксис запроса от значений параметров запроса. Суть любой SQL-инъекции - изменить синтаксис (текст, если угодно) запроса тем или иным образом. Если вы передаете текст запроса и параметры отдельно, не будет никакой возможности повлиять на синтаксис запроса из параметра запроса.

В случае поддержки со стороны СУБД, подтоговленные выражения PHP должны использовать возможности СУБД и передавать ей сначала текст запроса для компиляции, а уже потом, отдельно - параметры запроса.

Теоретически, проблемы могут быть только в случае, если prepared statements не поддерживаются самой СУБД и эмулируются PDO (т.е. на стороне скрипта, а не БД). Тогда косяки в реализации сборки конечного запроса могут сказаться на безопасности. В случае поддержки со стороны СУБД "реализовывать" просто напросто нечего - вы защищены от инъекций не за счет экранирования всего и вся, а за счет правильного подхода - никогда не смешивать сам запрос и его параметры.

Насколько мне известно, mysql уже давным-давно поддерживает prepared statements, поэтому не вижу смысла бояться их использовать. А даже если б это было не так, вероятность в том, что при ручной сборке запроса накосячите ВЫ - гораздо выше.

UPDATE: полезнейший коммент на странице php.net/manual/ru/pdo.prepare.php:
With PDO_MYSQL you need to remember about the PDO::ATTR_EMULATE_PREPARES option.

The default value is TRUE, like
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);

This means that no prepared statement is created with $dbh->prepare() call. With exec() call PDO replaces the placeholders with values itself and sends MySQL a generic query string.

The first consequence is that the call $dbh->prepare('garbage');
reports no error. You will get an SQL error during the $dbh->exec() call.
The second one is the SQL injection risk in special cases, like using a placeholder for the table name.

The reason for emulation is a poor performance of MySQL with prepared statements. Emulation works significantly faster.

Так что да, есть доля внезапности в поведении PDO. Я думаю стоит порыть инфы о настройке PDO::ATTR_EMULATE_PREPARES. Я считаю, что включать по-дефолту именно эмуляцию - это в высшей степени недальновидное решение. Проблемы MySQL затыкаются на стороне стандартной библиотеки языка....
Ответ написан
@mistergonza
PHP6 evangelist
За счет автоматического экранирования параметров.
php.net/manual/ru/pdo.prepared-statements.php
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Верьте только своему regex-выражению перед любой обработкой всех входных данных.
Ответ написан
trevoga_su
@trevoga_su
https://habrahabr.ru/post/148701/
советую прочитать эту статью от корки до корки
там все описано
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽