在MySQL中逃避正则表达式的用户输入的最佳方法是什么?

时间:2010-09-23 20:39:28

标签: php mysql regex escaping

我想接受用户输入,表示为$ dangerous_string,并将其用作MySQL查询中RegEx的一部分。

这样做的最佳方法是什么?我想将用户的字符串用作文字 - 如果它包含任何在MySQL RegEx中有意义的字符,那么这些字符实际上不应该影响我的正则表达式。

$dangerous_string = $_GET["string"];
//do something here
$dangerous_string = what_goes_here($dangerous_string);
$sql = "SELECT * FROM table WHERE search_column REGEX '" . $mysqli->real_escape_string("[[:<:]]$dangerous_string") . "'";

//etc....

3 个答案:

答案 0 :(得分:2)

AFAIK,MySQL正则表达式没有本地方法可以逃脱。您可以使用preg_quote(http://www.php.net/manual/en/function.preg-quote.php)在PHP中执行此操作,这可能会为您完成此任务,但显然不是为此目的而设计的。 / p>

如果我遇到你的情况,我首选的方法是在PHP中构建一个正则表达式白名单,然后你可以将它应用于你的危险字符串:

$safeString = preg_replace('/[^\w]/','',$dangerousString);

这将删除字符串中的所有非单词字符(即除A-Za-z0-9_之外的任何字符)。

注意我相信给出的其他答案不会删除/逃避正则表达式特殊字符,我认为这是你的要求。

答案 1 :(得分:0)

使用preg_quote并手动替换&

preg_quote接收字符串,并用反斜杠转义特殊字符。它是为PHP正则表达式而不是MySQL正则表达式设计的,并且它不会转义&,这是MySQL所需的。所以我们只需要像这样修改它:

function escape_regex_for_mysql($dangerous_string) {
    return preg_replace('/&/', '\\&', preg_quote($dangerous_string));
}

请注意,您仍然应该在顶部使用准备好的语句(或$mysqli->real_escape_string),如下所示:

$query = $wpdb->prepare(
    'SELECT * FROM table WHERE search_column REGEXP %s',
    '[[:<:]]' . escape_regex_for_mysql($dangerous_string)
);

理论价格:

让我们看一下MySQL的文档,看看哪些字符需要转义。 The documentation说:

  

MySQL> = 8.0.4使用Unicode国际组件(ICU)实现了正则表达式支持,它提供了完整的Unicode支持并且是多字节安全的。

让我们看一下the documentation for the ICU project

  

\(在集合之外)引用以下字符。必须将引号视为文字的字符是*? + [(){} ^ $ | \。

     

\(内部集)引用以下字符。必须将引号视为文字的字符是[] \,根据上下文可能需要引号的字符是-&

因此,需要转义的特殊字符列表为* ? + [ ] ( ) { } ^ $ \ . - &preg_quote转义了&以外的所有字符。它还会不必要地转义一些字符,但是MySQL将按预期处理。

或者,您可以将&作为第二个参数添加到preg_quote中,以便对其进行转义,例如preg_quote('AT&T', '&')

答案 2 :(得分:-2)

您需要确保正确处理报价和报价 在传递到数据库之前。最好的方法是:

   mysql_real_escape_string  ([php doc][1])

此方法在PHP和C ++ mysql客户端库中均可用。

这应该确保任何'dangerous_string'不再危险 并且可以在RegEx使用的带引号的字符串中使用。