【问题标题】:Why should you not use CONCAT() for static string literals?为什么不应该将 CONCAT() 用于静态字符串文字?
【发布时间】:2014-05-09 12:58:40
【问题描述】:

所以你有

$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

【问题讨论】:

    标签: php mysql sql-injection


    【解决方案1】:

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

    concat() 与prepared statement 一起使用并没有错。

    【讨论】:

    • 您能否详细说明您在使用“有意”和“严格”这两个词时的含义。谢谢
    • strict 表示严格,当您需要精确值来匹配给定值时。故意意味着故意部分匹配。无论如何,这只是我的猜测,试图解释不存在的“注射”的想法
    • 你如何看待秋葵汤的回应?
    • 不适用于mysql
    • @Victory 没有来自@TheodoreR.Smith 的声明,我们只能做(受过教育的)猜测。我无法想象使用CONCAT 会很危险的情况,除非在存储过程中动态构建 SQL 语句。 Lateral SQL Injection 技术表明,即使不涉及显式参数,也可能存在漏洞。但是,准备好的语句是 缓解技术,只要涉及到参数,就应该使用它。
    【解决方案2】:

    我认为@TheodoreR.Smith 的意思可能是Oracle 数据库中所谓的横向SQL 注入[1][2]

    它通过更改保存格式信息的环境变量(例如 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 容易发生这种环境变量操作。

    但是,在没有适当处理的情况下动态构建语句很容易发生 SQL 注入,无论它发生在应用程序还是数据库中。所以在存储过程中使用prepared statements也是强制性的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 2021-11-06
      • 2018-06-12
      • 1970-01-01
      相关资源
      最近更新 更多