为什么不将CONCAT()用于静态字符串文字?

时间:2014-03-30 04:47:45

标签: php mysql sql-injection

所以你有

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

另一个问题我发现这引起了安全问题,但为什么呢?

我发现了这个问题,一个沮丧的回答和一个赞成的评论,这就是为什么我要求

评论说

  

这不是正确的方法。您不应该将CONCAT()用于三个静态字符串文字,因为它会打开您特定类型的SQL注入(我忘记了名称)。 - 西奥多·R·史密斯

PHP PDO prepared statement -- mysql LIKE query

2 个答案:

答案 0 :(得分:2)

记住不存在的注射名称将是一项相当复杂的任务。

使用concat()准备好的陈述没有错。

答案 1 :(得分:1)

我认为@ TheodoreR.Smith可能意味着Oracle数据库 [1] [2] 中所谓的 Lateral SQL Injection

它通过更改包含NLS_DATE_FORMATNLS_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;

此处SYSDATENLS_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也是必需的。