Security for prepared SQL statement with REGEX in query

二次信任 提交于 2019-12-24 05:53:25

问题


I'm trying to use a prepared PDO statement for use in a database query that looks like the following, where the placeholders variables are represented by the numbers in quotes, i.e., "123" and "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".*')

My question is, would the best practice be to bind to the whole REGEX expression, or just the "123" and "456" variables (is that even possible in a REGEX expression), or something wholly different?

In other words, which is preferred, this:

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".*'");

Or this? (I know there would be some issues with double quotes surrounding the placeholder.)

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');

Thank you.


回答1:


Placeholders can't be quoted. Simple as that:

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

The first one is a placeholder, and works as expected. The other one is testing for equality against the character "question mark". It's not a placeholder anymore.

And then there's the problem of ? being a regex metacharacter as well. If placeholders COULD be quoted, then given

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

would that ? be a query placeholder, or is it the regex "zero-or-one" range operator?

If you want to use placeholders in regexes, you have to "build" the regex pattern

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

Exactly the same way as you would have to build a LIKE pattern:

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


来源:https://stackoverflow.com/questions/39171717/security-for-prepared-sql-statement-with-regex-in-query

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!