从文件中读取正则表达式是否安全?

时间:2008-10-28 03:04:08

标签: regex perl security

假设一个允许用户在配置文件中指定多个文本过滤器表达式的Perl脚本,是否有一种安全的方法让他们也可以输入正则表达式,而不会出现意外的副作用或代码执行?没有实际解析正则表达式并检查它们是否有问题的结构,那就是。不会有任何替代,只会匹配。

顺便说一下,有没有办法在实际使用之前测试指定的正则表达式是否有效?如果输入/foo (bar/之类的内容,我想发出警告。

谢谢,Z。

<小时/> 编辑:
感谢非常有趣的答案。我发现如果使用use re 'eval'编译指示,只会在正则表达式中评估以下危险结构:

(?{code})
(??{code})
${code}
@{code}

默认为no re 'eval';因此,除非我遗漏了某些内容,否则从文件中读取正则表达式应该是安全的,唯一的检查是Axeman发布的eval / catch。至少我在测试中无法隐藏任何邪恶内容。

再次感谢。 ž。

5 个答案:

答案 0 :(得分:13)

根据您所匹配的内容以及您正在运行的Perl版本,可能会有一些正则表达式通过使用过多的前瞻,外观和其他断言来充当有效的拒绝服务攻击。

最好只允许一个小的,众所周知的正则表达式模式子集,并在您和您的用户学习如何使用系统时谨慎扩展它。就像许多博客评论系统只允许一小部分HTML标签一样。

如果你需要对正则表达式进行复杂的分析,最终Parse :: RecDescent可能会有用。

答案 1 :(得分:11)

eval { 
    qr/$re/;
};
if ( $@  ) { 
    # do something
}

编译表达式,让您从错误中恢复。

你可以观察恶意表达,因为你只是通过寻找这些模式来进行匹配,这将允许任意代码运行:

(?: \( \?{1,2} \{  # '(' followed by '?' or '??', and then '{'
|   \@ \{ \s* \[   # a dereference of a literal array, which may be arbitrary code.
)

确保使用x标志进行编译。

答案 2 :(得分:5)

您可能需要做一定程度的卫生处理。例如,perlre手册页描述了以下构造:

(?{ code })

允许模式匹配中的可执行代码。

答案 3 :(得分:5)

我建议不要相信用户的任何正则表达式。如果您确实这样做,请在污染(-T)模式下运行perl。在这种情况下,您需要某种形式的验证。您可以使用现有的YAPE::Regex regexp解析器而不是使用Parse :: RecDescent编写自己的正则表达式解析器,这可能更快,由专家编写并且像魅力一样工作。

最后,从perl 5.10.0开始,你可以将不同的正则表达式引擎插入perl(词法!)。您可以检查是否存在功能较弱的正则表达式引擎,其语法更容易验证。如果您想沿着这条路走下去,请阅读the API descriptionAvar's re::engine::Plugin,或者通常查看Avar's plugin engines中的任何一个。

答案 4 :(得分:0)

Safe模块在​​编译/执行不受信任的正则表达式方面是否有用?