【发布时间】:2014-01-05 00:48:43
【问题描述】:
如果我在服务器上使用用户定义的输入字符串运行用户定义的正则表达式,是否存在任何安全问题?我问的不是一种语言,而是任何一种语言,PHP 是我想了解的主要语言之一。
例如,如果我有以下代码:
<?php
if(isset($_POST['regex'])) {
preg_match($_POST['regex'], $_POST['match'], $matches);
var_dump($matches);
}
?>
<form action="" method="post">
<input type="text" name="regex">
<textarea name="match"></textarea>
<input type="submit">
</form>
如果这不是一个受控环境(即用户不能被信任),上述代码的风险是什么?如果为其他语言编写类似的代码,这些其他语言是否存在风险?如果是,哪些语言构成威胁?
我已经发现了“邪恶的正则表达式”,但是,无论我在计算机上尝试什么,它们似乎都可以正常工作,见下文。
PHP
<?php
php > preg_match('/^((ab)*)+$/', 'ababab', $matches);var_dump($matches);
array(3) {
[0] =>
string(6) "ababab"
[1] =>
string(0) ""
[2] =>
string(2) "ab"
}
php > preg_match('/^((ab)*)+$/', 'abababa', $matches);var_dump($matches);
array(0) {
}
JavaScript
phantomjs> /^((ab)*)+$/g.exec('ababab');
{
"0": "ababab",
"1": "ababab",
"2": "ab",
"index": 0,
"input": "ababab"
}
phantomjs> /^((ab)*)+$/g.exec('abababa');
null
这让我相信 PHP 和 JavaScript 具有针对恶意正则表达式的故障安全机制。基于此,我希望其他语言具有类似的功能。
这是一个正确的假设吗?
最后,对于任何或所有可能有害的语言,有没有办法确保正则表达式不会造成损害?
【问题讨论】:
-
这些正则表达式在用于恶意制作的非常长的字符串时是邪恶的。
-
使用
e修饰符(在 PHP 中)将评估某些内容(您可能不想要),请参阅 the manual -
@SLaks,当你说“长字符串”时,知道我们在谈论多长时间吗?
-
@kingkero,我知道,但这已被弃用,仅适用于
preg_replace()
标签: javascript php regex perl