假设一个允许用户在配置文件中指定多个文本过滤器表达式的Perl脚本,是否有一种安全的方法让他们也可以输入正则表达式,而不会出现意外的副作用或代码执行?没有实际解析正则表达式并检查它们是否有问题的结构,那就是。不会有任何替代,只会匹配。
顺便说一下,有没有办法在实际使用之前测试指定的正则表达式是否有效?如果输入/foo (bar/
之类的内容,我想发出警告。
谢谢,Z。
<小时/> 编辑:
use re 'eval'
编译指示,只会在正则表达式中评估以下危险结构:
(?{code})
(??{code})
${code}
@{code}
默认为no re 'eval'
;因此,除非我遗漏了某些内容,否则从文件中读取正则表达式应该是安全的,唯一的检查是Axeman发布的eval / catch。至少我在测试中无法隐藏任何邪恶内容。
再次感谢。 ž。
答案 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)
答案 3 :(得分:5)
我建议不要相信用户的任何正则表达式。如果您确实这样做,请在污染(-T)模式下运行perl。在这种情况下,您需要某种形式的验证。您可以使用现有的YAPE::Regex regexp解析器而不是使用Parse :: RecDescent编写自己的正则表达式解析器,这可能更快,由专家编写并且像魅力一样工作。
最后,从perl 5.10.0开始,你可以将不同的正则表达式引擎插入perl(词法!)。您可以检查是否存在功能较弱的正则表达式引擎,其语法更容易验证。如果您想沿着这条路走下去,请阅读the API description,Avar's re::engine::Plugin,或者通常查看Avar's plugin engines中的任何一个。
答案 4 :(得分:0)
Safe模块在编译/执行不受信任的正则表达式方面是否有用?