我的(基于Perl的)应用程序需要让用户输入正则表达式,以匹配幕后的各种字符串。到目前为止,我的计划是采用字符串并将其包装成类似
的内容$regex = eval { qr/$text/ };
if (my $error = $@) {
# mangle $error to extract user-facing message
($text
提前删除了换行符,因为它实际上是多行文本字段中的多个正则表达式split
)。
这样做是否存在任何潜在的安全风险 - 一些可能导致任意代码执行的奇怪输入? (除了CVE-2007-5116等正则表达式引擎中的缓冲区溢出漏洞)。如果是这样,有没有办法减轻它们?
有更好的方法吗?任何Perl模块都有助于抽象将用户输入转换为正则表达式的操作(例如提取错误消息......或提供像/i
这样的修饰符,我在这里并不严格需要,但会很好)?我搜索了CPAN并没有找到很多有希望的东西,但却有可能让我错过了一些东西。
答案 0 :(得分:6)
使用不受信任的输入作为正则表达式会创建拒绝服务漏洞,如perlsec中所述:
正则表达式 - Perl的正则表达式引擎被称为NFA(非确定性有限自动机),其中包括 意味着如果正则表达式可能以多种方式匹配,它可以相当容易地消耗大量的时间和空间。 仔细制作正则表达式可能会有所帮助,但通常情况下确实没有太多可以做的事情(“Mastering Regular”一书 表达式“是必读的,请参阅perlfaq2。”Perl耗尽内存后,空间不足就会显现出来。
答案 1 :(得分:4)
使用(?{ code })
结构,用户输入可用于执行任意代码。请参阅perlre#code中的示例及其所在的位置
local $cnt = $cnt + 1,
将其替换为表达式
system("rm -rf /home/fennec"); print "Ha ha.\n";
(实际上,不要这样做。)
答案 2 :(得分:4)
在The Monastery进行了一些讨论。
TLDR:use re::engine::RE2 -strict => 1;
确保将-strict => 1
添加到您的use语句或re :: engine :: RE2将重新回到Perl的重新开始。
以下是project on GitHub所有者Paul Wankadia(junyer)的引文:
RE2的设计和实现具有明确的目标,即能够在没有风险的情况下处理来自不受信任的用户的正则表达式。其主要保证之一是匹配时间在输入字符串的长度上是线性的。它的编写也考虑了生产问题:解析器,编译器和执行引擎通过在可配置的预算内工作来限制其内存使用 - 在耗尽时优雅地失败 - 并且它们通过避免递归来避免堆栈溢出。
总结重点:
默认情况下,任意代码执行都是安全的,但添加“no re'eval';”防止PERL5OPT或其他任何事情?从你的设置。我不确定这样做是否会阻止一切。
使用BSD :: Resource(甚至在Linux上)的子进程(fork)来限制内存并在超时后终止子进程。
答案 3 :(得分:3)
最好的方法,就是不要让用户拥有太多的特权。提供足够的界面供用户做他们想做的事。 (就像ATM机只有各种选项的按钮,不需要键盘输入)。当然,如果您需要用户键入输入,然后提供文本框,然后在后端,使用Perl处理请求(例如,清理等)。让用户输入正则表达式的动机是搜索字符串模式吗?那么在这种情况下,最简单和最安全的方法是告诉他们只输入字符串。然后在后端,使用Perl的正则表达式来搜索它。还有其他令人信服的理由让用户输入正则表达式吗?
答案 4 :(得分:1)
也许您可以使用不具有危险代码标记支持的其他正则表达式引擎。
我没有尝试过,但perl有一个PCRE。您也可以使用this info on creating custom regex engines限制或删除代码支持。