代码之家  ›  专栏  ›  技术社区  ›  Ryan C. Thompson

在哪些语言中,使用用户提供的正则表达式是一个安全漏洞?

  •  12
  • Ryan C. Thompson  · 技术社区  · 14 年前

    编辑:TChrist告诉我,我最初对Perl不安全的指责是没有根据的。然而,这个问题仍然存在。

    我知道在Perl中,可以在正则表达式中嵌入任意代码,因此显然接受用户提供的regex并进行匹配可以允许任意代码执行,这是一个明显的安全漏洞。 但是对于所有使用正则表达式的语言来说,这是真的吗?所有使用“Perl兼容”正则表达式的语言都是这样吗?哪些语言是用户提供的可安全使用的regex,哪些语言允许任意代码执行或其他安全漏洞?

    8 回复  |  直到 6 年前
        1
  •  17
  •   Wolph    14 年前

    在大多数语言中,允许用户提供正则表达式意味着允许拒绝服务攻击。

    有些类型的正则表达式执行起来非常需要CPU。因此,一般来说,允许用户输入将在远程系统上执行的正则表达式是一个坏主意。

    有关详细信息,请阅读此页: http://www.regular-expressions.info/catastrophic.html

        2
  •  6
  •   tchrist    14 年前

    这不是真的:不能通过在经过计算的regex中隐藏代码回调来在Perl中执行代码回调。这是禁止的。你必须用一个词法作用域来具体地重写它。

    use re "eval";
    

    如果希望插值和代码转义都以相同的模式发生。

    手表:

    % perl -le '$x = "(?{ die 'naughty' })"; "aaa" =~ /$x/'
    Eval-group not allowed at runtime, use re 'eval' in regex m/(?{ die naughty })/ at -e line 1.
    Exit 255
    
    % perl -Mre=eval -le '$x = "(?{ die 'naughty' })"; "aaa" =~ /$x/'
    naughty at (re_eval 1) line 1.
    Exit 255
    
        3
  •  2
  •   Gabe Timothy Khouri    14 年前

    它通常是动态语言, eval 具有执行正则表达式代码的功能。在静态语言(即需要单独编译步骤的语言)中,通常无法执行未编译的代码,因此不可能从regex中评估代码。

    如果没有在regex中嵌入代码的方法,用户所能做的最糟糕的事情就是编写一个需要很长时间才能评估的regex。

        4
  •  2
  •   Community CDub    8 年前

    1)在regex库中发现漏洞,例如 buffer overflow that affects Webkit 并允许任何攻击者通过从javascript访问regex库来获得远程代码执行。

    2) It is a DoS condition in C#.

    3)由于修改器的原因,用户提供的regex可以用于php。添加/e修饰符将评估匹配。在这种情况下,系统将被评估。

    preg_replace("/.*/e","system('echo /etc/passwd')");

    或以脆弱性的形式:

    preg_replace($_GET['regex'],$_GET['check']);

        5
  •  1
  •   mjfgates    14 年前

    正则表达式 一种程序设计语言。我不认为他们是图灵完成,但他们足够接近,让你的用户进入你的网站是允许其他人在你的服务器上运行代码。QED,是的,这是一个安全漏洞。

    你也许可以摆脱允许任何你想要使用的regexp语言的子集,白名单一组特殊的结构,使它不足以让人汗流浃背…其他人已经提到了筑巢的可能厄运和*。你愿意让人们从你的服务器上下载多少取决于你自己。就个人而言,我愿意让他们有一个SQL“contains”语句,也许还有一个“between()”。:)

        6
  •  1
  •   Andrew Grimm atk    14 年前

    我怀疑鲁比会允许 /#{system("rm -rf really_important_directory")}/ -这是你担心的事吗?

        7
  •  0
  •   Reinderien    14 年前

    afaik,您可以在c中安全地完成:您可以将regex字符串提供给regex构造函数,如果解析失败,它将抛出。我不确定其他人。

        8
  •  0
  •   Dio Phung    6 年前

    无论编程语言如何,用户提供的regex或一般用户输入都不应被视为安全的。如果您的程序不能做到这一点,那么它很容易受到精心设计的输入的攻击。

    对于regex,它可以是 ReDos :regex拒绝服务。基本上,一个regex需要消耗大量的CPU和内存来处理。

    例如:如果您尝试评估此regex

    ^(([a-z])+.)+[A-Z]([a-z])+$
    

    在此输入上:

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
    

    你会注意到它可能会挂起——这叫做灾难性的回溯。你自己看看这里: https://regex101.com/r/Qhn3Vb/1

    阅读有关regex-dos的更多信息: https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS


    底线:永远不要假设用户输入是安全的!

    推荐文章