【问题标题】:User defined regular expression security concerns用户定义的正则表达式安全问题
【发布时间】: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


【解决方案1】:

当您使用用户定义的字符串运行用户定义的正则表达式时,用户可能会制作一个灾难性的回溯正则表达式,通常带有 failing 输入在您的系统上造成拒绝服务。

使用您的示例^((ab)*)+$,您需要稍长的失败输入以导致灾难性回溯生效:"ababababababababababababababababababababababd"

  • 对于 PHP 版本,对 preg_last_error 的调用应返回 PREG_BACKTRACK_LIMIT_ERROR
  • 对于 JS 版本,上面的代码在 Firefox 26 中不会导致灾难性的回溯,浏览器返回false。在 Chrome 31.0.1650.63 m 和 Internet Explorer 11 上,可以观察到灾难性的回溯。

根据语言/库的 API,API 可能会提供限制回溯尝试次数或设置操作超时的选项;强烈建议您设置限制以防止服务器上出现 DoS。

  • PCRE默认在1000万次回溯尝试后停止,次数可配置。
  • .NET Regex 类附带一个 API 来限制匹配所用的时间。

如果语言没有自带这么方便的API,强烈建议你实现自己的超时机制来超时执行。

除非正则表达式引擎的规范包括防止灾难性回溯的要求(例如 PCRE 具有 默认 回溯限制),否则您不应依赖特定实现的行为(如 Firefox 的情况如上所述)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 2011-01-25
    相关资源
    最近更新 更多