有没有办法将恶意代码放入正则expression式?

我想添加正则expression式searchfunction到我的公共网页。 除了HTML编码的输出,我需要做任何事情来防止恶意用户input?

谷歌search是由解决相反的问题的人淹没 – 使用正则expression式来检测恶意input – 我不感兴趣。在我的情况下,用户input一个正则expression式。

我将在.NET(C#)中使用正则expression式库。

拒绝服务问题

正则expression式最常见的问题是通过病态模式的拒绝服务攻击,这些病态模式呈指数级甚至超级指数级。 – 似乎要永远解决。 这些可能只会显示在特定的input数据上,但通常可以创build一个,这并不重要。

这些是哪些将取决于你正在使用的正则expression式编译器有多聪明,因为其中的一些可以在编译时检测到。 实现recursion的正则expression式编译器通常有一个内置的recursion深度计数器来检查非进度。

Russ Cox关于正则expression式匹配的精彩2007年论文可以是简单而快速的(但是在Java,Perl,PHP,Python,Ruby等方面很慢)讨论了大多数现代的NFA,这些都来自Henry Spencer的代码,严重的性能下降,但汤普森风格的NFA没有这样的问题。

如果你只承认可以通过DFA解决的模式,你可以将它们编译成它们,并且运行得更快,可能要快得多。 但是,这需要时间 。 考克斯论文提到了这种方法及其伴随的问题。 这一切都归结为经典的时空交易。

有了DFA,您可以花更多的时间来构build它(并分配更多的状态),而使用NFA时,您可以花更多的时间来执行它,因为它可以同时处于多个状态,并且回溯可以吃掉午餐和CPU。

拒绝服务解决scheme

解决这些模式的最合理的方法,是在一场与宇宙热死的比赛中失败的一端,是用一个计时器来包装它们,这个计时器有效地放置了执行的最大时间。 通常这会比大多数HTTP服务器提供的默认超时less得多。

有很多种方法可以实现这些,从C级的简单alarm(N)到某种try {}阻塞捕获警报types的exception,一路产生一个特殊创build的新线程时序约束build立在它的权利。

代码标注

在允许使用代码标注的正则expression式语言中, 应该提供一些允许或禁止这些string的机制。 即使代码标注仅用您正在使用的语言进行编码,您也应该限制它们; 他们不必能够调用外部代码,尽pipe如果他们可以的话,你会遇到更大的问题。

例如,在Perl中,不能在由string插值创build的正则expression式中创build代码标注(因为它们是在运行时编译的),除非特殊的词汇范围的附注use re "eval"; 在当前范围内活跃。

这样,没有人可以潜入代码标注来运行系统程序,例如rm -rf * 。 由于代码标注对安全性非常敏感,Perl会在所有插入的string中禁用它们,并且必须自行重新启用它们。

用户定义\ P {roperties}

还有一个与Unicode样式属性相关的安全敏感问题,比如\pM\p{Pd}\p{Pattern_Syntax}或者\p{Script=Greek}可能存在于一些正则expression式编译器中,符号。

问题是,在其中一些可能的属性集是用户可扩展的。 这意味着您可以将自定义属性设置为某些特定命名空间中的命名函数的实际代码调用,如\p{GoodChars}\p{Class::Good_Characters} 。 你的语言如何处理这些可能是值得关注的。

沙箱

在Perl中,通过Safe模块的沙盒隔离区将控制命名空间的可见性。 其他语言提供类似的沙盒技术。 如果这些设备可用,则可能需要查看它们,因为它们专门用于有限执行不受信任的代码。

添加到tchrist的优秀答案:编写“Regular Expression”页面的Russ Cox也发布了代码! re2是一个C ++库,它保证了O(length_of_regex)运行时和可configuration的内存使用限制。 它在Google中使用,以便您可以在Google代码search中键入正则expression式 – 这意味着它已经过testing。

是。

正则expression式可以用来执行DOS攻击 。
没有简单的解决scheme。

你会想读这篇文章:

不安全的上下文切换:为生存性接收正则expression式本文更多地介绍正则expression式引擎(例如PCRE)可能出现的问题,但它可能有助于理解您所面临的问题。

你不仅要担心匹配本身,而且你如何做匹配。 例如,如果您的input在正式expression式引擎的途中经历某种eval阶段或命令replace,那么可能会有一些代码在模式中执行。 或者,如果您的正则expression式语法允许embedded式命令,您也必须谨慎。 由于您没有在您的问题中指定语言,所以很难确定所有的安全隐患。

testingRegEx的安全问题(至less在Windows中)的一个好方法是最近由Microsoft发布的SDL RegEx模糊工具 。 这可以帮助避免病态的RegExbuild设。