Почему вы не должны использовать CONCAT () для статических строковых литералов?

Так что у тебя есть

$sql = "SELECT * FROM `table` WHERE `some_text_field` LIKE CONCAT('%', ?, '%')"; $stmt = $dbh->prepare($sql); $stmt->execute(array($_POST['badies_code'])); 

И, глядя на другой вопрос, я обнаружил, что это вызывает проблему безопасности, но почему?

Я нашел этот вопрос, нисходящий ответ и высказанный комментарий, поэтому я спрашиваю

Комментарий сказал

Это неправильный способ сделать это. Вы не должны использовать CONCAT () для трех статических строковых литералов, так как он открывает вам определенный тип SQL-инъекций (я забыл имя). – Теодор Р. Смит

Отчет PHP PDO – запрос mysql LIKE

Я думаю, что то, что @ TheodoreR.Smith, возможно, имел в виду так называемый Lateral SQL Injection в Oracle Database [1] [2] .

Он работает путем изменения переменных среды, содержащих информацию о формате, такую ​​как NLS_DATE_FORMAT , или NLS_NUMERIC_CHARACTERS , которые затем используются в хранимой процедуре, которая строит и выполняет инструкцию динамически (здесь используется конкатенация строк, обозначаемая операторами || ):

 CREATE OR REPLACE PROCEDURE date_proc IS stmt VARCHAR2(200); v_date DATE := SYSDATE; BEGIN stmt := 'select object_name from all_objects where created = ''' || v_date || ''''; EXECUTE IMMEDIATE stmt; END; 

Здесь SYSDATE возвращает текущую дату в формате, указанном в NLS_DATE_FORMAT . Хотя процедура не имеет параметров, изменение формата даты на ' or 1=1-- :

 ALTER SESSION SET NLS_DATE_FORMAT = ''' or 1=1--' 

Итоговый оператор:

 select object_name from all_objects where created = '' or 1=1--' 

Эта манипуляция переменной окружения специфична для Oracle Database. И снова это можно смягчить, используя подготовленные заявления:

 CREATE OR REPLACE PROCEDURE date_proc IS stmt VARCHAR2(200); v_date DATE := SYSDATE; BEGIN stmt := 'select object_name from all_objects where created = :date'; EXEC SQL PREPARE prepared_stmt FROM :stmt; EXEC SQL EXECUTE prepared_stmt USING :v_date; end; 

Я не знаю, что MySQL склонен к такой манипуляции с переменными среды.

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

Было бы довольно сложной задачей запомнить имя инъекции, которая не существует.

Нет ничего плохого в использовании concat() с подготовленным оператором.