【问题标题】:Security for prepared SQL statement with REGEX in query查询中使用 REGEX 的准备好的 SQL 语句的安全性
【发布时间】:2016-08-26 17:26:34
【问题描述】:

我正在尝试使用准备好的 PDO 语句用于如下所示的数据库查询,其中占位符变量由引号中的数字表示,即“123”和“456”:

SELECT `user_ID` as `ID` 
FROM `usermeta` 
WHERE (`meta_key` = 'custom_fields') 
AND (`meta_value` REGEXP '.*"ABC";.*s:[0-9]+:"123".*') 
AND (`meta_value` REGEXP '.*"DEF";.*s:[0-9]+:"456".*')

我的问题是,最佳做法是绑定到整个 REGEX 表达式,还是只绑定“123”和“456”变量(这在 REGEX 表达式中甚至可能),还是完全不同的?

换句话说,这是首选:

SELECT `user_ID` as `ID` 
FROM `usermeta` 
WHERE (`meta_key` = 'custom_fields') 
AND (`meta_value` :REGEXP1) 
AND (`meta_value` :REGEXP2)

$stmt->bindParam(':REGEXP1', "REGEXP '.*"ABC";.*s:[0-9]+:"123".*'");
$stmt->bindParam(':REGEXP2', "REGEXP '.*"DEF";.*s:[0-9]+:"456".*'");

还是这个? (我知道占位符周围的双引号会有一些问题。)

SELECT `user_ID` as `ID` 
FROM `usermeta` 
WHERE (`meta_key` = 'custom_fields') 
AND (`meta_value` REGEXP '.*"ABC";.*s:[0-9]+:":value1".*') 
AND (`meta_value` REGEXP '.*"DEF";.*s:[0-9]+:":value2".*')

$stmt->bindParam(':value1', '123');
$stmt->bindParam(':value2', '456');

谢谢。

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    不能引用占位符。就这么简单:

    SELECT ... WHERE foo = ?
    SELECT ... WHERE foo = '?'
    

    第一个是占位符,按预期工作。另一个是针对字符“问号”测试是否相等。它不再是占位符了。

    还有? 也是一个正则表达式元字符的问题。如果可以引用占位符,则给出

    SELECT ... WHERE foo REGEXP '^.?' 
    

    ? 是查询占位符,还是正则表达式“零或一”范围运算符?

    如果你想在正则表达式中使用占位符,你必须“构建”正则表达式模式

    SELECT ... WHERE foo REGEXP concat('^.', ?)
    

    与构建LIKE 模式的方式完全相同:

    SELECT ... WHERE foo LIKE '%?%' // wrong
    SELECT ... WHERE foo LIKE concat('%', ?, '%') // right
    

    【讨论】:

    • 太棒了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 2010-11-21
    • 2012-08-12
    相关资源
    最近更新 更多