所以你有
$sql = "SELECT * FROM `table` WHERE `some_text_field` LIKE CONCAT('%', ?, '%')";
$stmt = $dbh->prepare($sql);
$stmt->execute(array($_POST['badies_code']));
另一个问题我发现这引起了安全问题,但为什么呢?
我发现了这个问题,一个沮丧的回答和一个赞成的评论,这就是为什么我要求
评论说
这不是正确的方法。您不应该将CONCAT()用于三个静态字符串文字,因为它会打开您特定类型的SQL注入(我忘记了名称)。 - 西奥多·R·史密斯
答案 0 :(得分:2)
记住不存在的注射名称将是一项相当复杂的任务。
使用concat()
准备好的陈述没有错。
答案 1 :(得分:1)
我认为@ TheodoreR.Smith可能意味着Oracle数据库 [1] [2] 中所谓的 Lateral SQL Injection 。
它通过更改包含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数据库。而且,可以使用预先准备的语句来缓解它:
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很容易受到这种环境变量的操纵。
但是,无论是在应用程序中还是在数据库中,都会在没有正确处理的情况下动态构建语句。因此,在存储过程中使用prepared statements也是必需的。