Так что у тебя есть
$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()
с подготовленным оператором.