查询中使用REGEX准备的SQL语句的安全性

时间:2016-08-26 17:26:35

标签: php mysql pdo

我试图使用准备好的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');

谢谢。

1 个答案:

答案 0 :(得分:1)

不能引用占位符。很简单:

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

第一个是占位符,按预期工作。另一个是测试与角色"问号"的平等。它不再是占位符了。

然后还存在?作为正则表达式元字符的问题。如果占位符可以引用,则给出

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

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

如果你想在正则表达式中使用占位符,你必须" build"正则表达式

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

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

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