Як саме плейсхолдери (підготовлені вирази) захищають від SQL-ін’єкцій
Підготовлені вирази захищають від ін'єкцій SQL тим, що відокремлюють синтаксис запиту від значень параметрів запиту. Суть будь-якої SQL-ін'єкції – змінити синтаксис (текст, якщо завгодно) запиту тим чи іншим чином. Якщо ви надсилаєте текст запиту та параметри окремо, не буде ніякої можливості вплинути на синтаксис запиту з параметра запиту.
У разі підтримки з боку СУБД, підсумовані вирази PHP повинні використовувати можливості СУБД і передавати їй спочатку текст запиту для компіляції, а потім, окремо - параметри запиту.
Теоретично, проблеми можуть бути лише у разі, якщо prepared statements не підтримуються самої СУБД і емулюються PDO (тобто за скрипту, а чи не БД). Тоді косяки в реалізації складання кінцевого запиту можуть позначитися на безпеці. У разі підтримки з боку СУБД "реалізовувати" просто нічого - ви захищені від ін'єкцій не за рахунок екранування всього і вся, а за рахунок правильного підходу - ніколи не змішувати сам запит та його параметри.
Наскільки мені відомо, mysql вже давно підтримує prepared statements, тому не бачу сенсу боятися їх використовувати. А навіть якщо б це було не так, ймовірність у тому, що при ручному складанні запиту накосячіть ВИ – набагато вище.
The default value is TRUE, як $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);
Це означає, що не preparated statement is created with $dbh->prepare() call. З exec() call PDO replaces the placeholders with values itself and sends MySQL generic query string.
The first consequence is that the call $dbh->prepare('garbage'); reports no error. You will get an SQL error під час$dbh->exec() call. Завжди один є SQL введення ризику в особливих випадках, як використовуючи placeholder for table name.
Причиною для emulation є достатня продуктивність MySQL з preparated statements. Emulation works значною мірою faster. Так що так, є частка раптовості у поведінці PDO. Я думаю варто порити інформації про налаштування PDO::ATTR_EMULATE_PREPARES. Я вважаю, що включати по-дефолту саме емуляцію - це надзвичайно недалекоглядне рішення. Проблеми MySQL затикаються за стандартної бібліотеки мови.