假设一个允许用户在配置文件中指定多个文本过滤器表达式的Perl脚本,是否有一种安全的方法让他们也可以输入正则表达式,而不会出现意外的副作用或代码执行?没有实际解析正则表达式并检查它们是否有问题的结构,那就是.不会有任何替代,只有匹配.
顺便说一句,有没有办法在实际使用它之前测试指定的正则表达式是否有效?如果/foo (bar/
输入了类似的内容,我想发出警告.
谢谢,Z.
use re 'eval'
pragma ,下面的危险结构只会在regex中进行评估:
(?{code}) (??{code}) ${code} @{code}
默认是no re 'eval'
; 因此,除非我遗漏了某些内容,否则从文件中读取正则表达式应该是安全的,唯一的检查是Axeman发布的eval/catch.至少我在测试中无法隐藏任何邪恶内容.
再次感谢.Z.
根据您所匹配的内容以及您正在运行的Perl版本,可能会有一些正则表达式通过使用过多的前瞻,后观和其他断言来充当有效的拒绝服务攻击.
您最好只允许一个小的,众所周知的正则表达式模式子集,并在您和您的用户学习如何使用系统时谨慎扩展它.与许多博客评论系统仅允许一小部分HTML标签的方式相同.
如果你需要对正则表达式进行复杂的分析,最终Parse :: RecDescent可能会变得有用.
这个
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
标志编译它.
您可能需要进行一定程度的卫生处理.例如,perlre手册页描述了以下构造:
(?{ code })
它允许模式匹配中的可执行代码.
我建议不要相信用户的任何正则表达式.如果您确实这样做,请在污染(-T)模式下运行perl.在这种情况下,您需要某种形式的验证.如同另一个答案所示,您应该使用现有的YAPE :: Regex regexp解析器而不是使用Parse :: RecDescent编写自己的正则表达式解析器,它可能更快,由专家编写并且像魅力一样工作.
最后,从perl 5.10.0开始,你可以将不同的正则表达式引擎插入perl(词法!).您可以检查是否存在功能较弱的正则表达式引擎,其语法更容易验证.如果你想沿着这条路走下去,请阅读API描述,Avar的re :: engine :: Plugin,或者通常查看任何Avar的插件引擎.