如何安全地使用用户输入的正则表达式?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何安全地使用用户输入的正则表达式?相关的知识,希望对你有一定的参考价值。

我的(基于Perl的)应用程序需要让用户输入正则表达式,以匹配幕后的各种字符串。到目前为止,我的计划是将字符串包装成类似的东西

$regex = eval { qr/$text/ };
if (my $error = $@) { 
   # mangle $error to extract user-facing message

$text提前被剥去了换行符,因为它实际上是多行文本字段中的多个正则表达式,我split)。

这样做是否存在任何潜在的安全风险 - 一些可能导致任意代码执行的奇怪输入? (除了CVE-2007-5116等正则表达式引擎中的缓冲区溢出漏洞)。如果是这样,有没有办法减轻它们?

有一个更好的方法吗?任何Perl模块都有助于抽象将用户输入转换为正则表达式的操作(例如提取错误消息......或提供像/i这样的修饰符,我在这里并不严格需要,但会很好)?我搜索了CPAN并没有找到很多有希望的东西,但却有可能让我错过了一些东西。

答案

使用(?{ code })构造,用户输入可用于执行任意代码。请参阅perlre#code中的示例以及它所说的位置

local $cnt = $cnt + 1,

用表达式替换它

system("rm -rf /home/fennec"); print "Ha ha.
";

(实际上,不要这样做。)

另一答案

使用不受信任的输入作为正则表达式会创建拒绝服务漏洞,如perlsec中所述:

正则表达式 - Perl的正则表达式引擎被称为NFA(非确定性有限自动机),除其他外,它意味着如果正则表达式可能以多种方式匹配,它可以相当容易地消耗大量的时间和空间。仔细制作正则表达式可能有所帮助,但通常情况下确实没有多少人可以做(“掌握正则表达式”一书是必读的,请参阅perlfaq2)。 Perl耗尽内存后,空间不足就会显现出来。

另一答案

The Monastery有一些关于此的讨论。

TLDR:use re::engine::RE2 -strict => 1;

确保将-strict => 1添加到您的use语句中,或者re :: engine :: RE2将回退到Perl的re。

以下是来自project on GitHub所有者Paul Wankadia(junyer)的引文:

RE2的设计和实现的明确目标是能够在没有风险的情况下处理来自不受信任的用户的正则表达式。其主要保证之一是匹配时间在输入字符串的长度上是线性的。它的编写也考虑了生产问题:解析器,编译器和执行引擎通过在可配置的预算内工作来限制其内存使用 - 在耗尽时优雅地失败 - 并且它们通过避免递归来避免堆栈溢出。

总结一下重点:

  • 默认情况下,任意代码执行都是安全的,但添加“no re'eval';”防止PERL5OPT或其他任何事情?从你的设置。我不确定这样做是否会阻止一切。
  • 使用带有BSD :: Resource(甚至在Linux上)的子进程(fork)来限制内存并在超时后终止子进程。
另一答案

最好的方法,就是不要让用户拥有太多的特权。提供足够的界面供用户做他们想做的事。 (就像ATM机只有各种选项的按钮,不需要键盘输入)。当然,如果您需要用户键入输入,然后提供文本框,然后在后端,使用Perl处理请求(例如,清理等)。让用户输入正则表达式的动机是搜索字符串模式吗?那么在这种情况下,最简单和最安全的方法是告诉他们只输入字符串。然后在后端,使用Perl的正则表达式来搜索它。还有其他令人信服的理由让用户输入正则表达式吗?

另一答案

也许您可以使用不具有危险代码标记支持的不同正则表达式引擎。

我没有尝试过但是有一个用于perl的PCRE。您也可以使用this info on creating custom regex engines限制或删除代码支持。

以上是关于如何安全地使用用户输入的正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

Web安全基础

Regular Expression常用的正则表达式

在js中正则表达式如何判断用户输入的内容只能是数字和字母

在js中正则表达式如何判断用户输入的内容只能是数字和字母

如何使用 jQuery 将正则表达式应用于输入?

如何使用正则表达式检查用户输入是不是仅包含特殊字符?