有什么方法可以将恶意代码放入正则表达式中吗?
我想向我的公共网页添加正则表达式搜索功能。 除了编码输出的HTML,我是否需要做任何事情来防止恶意用户输入?
谷歌搜索被解决相反问题的人淹没 - 使用正则表达式来检测恶意输入 - 我不感兴趣。在我的场景中,用户输入是正则表达式。
我将在.NET中使用正则表达式库(C#)。
拒绝服务问题
正则表达式最常见的问题是通过呈指数级甚至超级指数的病态模式进行拒绝服务攻击! - 所以似乎需要永远解决。 这些可能只会显示特定的输入数据,但通常可以创建一个,其中这并不重要。
这些都取决于你正在使用的正则表达式编译器有多聪明,因为其中一些可以在编译期间被检测到。 实现递归的正则表达式编译器通常有一个内置的递归深度计数器来检查非递进。
Russ Cox出色的2007年关于正则表达式匹配的文章可以简单快速(但在Java,Perl,PHP,Python,Ruby ......中很慢)讨论了大多数现代NFA的方法,这些方法似乎都来自Henry Spencer的代码,遭受严重的性能下降,但汤普森风格的NFA没有这种问题。
如果您只承认可以通过DFA解决的模式,那么您可以将它们编译为它们,并且它们运行得更快,可能要快得多。 但是,这需要时间。 考克斯论文提到了这种方法及其伴随的问题。 这一切都归结为经典的时空交易。
使用DFA时,您需要花费更多时间来构建它(并分配更多状态),而使用NFA时,您需要花更多时间来执行它,因为它可以同时处于多个状态,并且回溯可以吃掉午餐 - 以及CPU。
拒绝服务解决方案
解决这些模式的最合理的方式,就是在宇宙热死的比赛中失败的一端是用一个计时器来包装它们,这样就可以有效地为其执行所需的最大时间。 通常这会比大多数HTTP服务器提供的默认超时少得多。
有很多种方法可以实现这些功能,从C级别的简单alarm(N)
到某种try {}
阻塞捕获警报类型的异常,一路产生一个专门用时序约束正好嵌入其中。
代码标注
在允许使用代码标注的正则表达式语言中,应提供一些允许或禁止将要编译的字符串的机制。 即使代码标注仅用您正在使用的语言编码,您也应该限制它们; 他们不必调用外部代码,尽管如果他们可以的话,你会遇到更大的问题。
例如,在Perl中,不能在通过字符串插值创建的正则表达式中创建代码标注(因为它们会在运行时编译),除非特殊的词汇作用域编译指示use re "eval";
在当前范围内处于活动状态。
这样,没有人可以潜入代码标注中运行系统程序,例如rm -rf *
。 由于代码标注对安全敏感,所以Perl会在所有插入的字符串中禁用它们,并且您必须自行重新启用它们。
用户定义 P {roperties}
还有一个与Unicode风格属性相关的安全敏感问题 - 如pM
, p{Pd}
, p{Pattern_Syntax}
或p{Script=Greek}
- 可能存在于某些正则表达式编译器中,符号。
问题在于,其中一些可能的属性集是用户可扩展的。 这意味着您可以将自定义属性设置为某些特定命名空间中指定函数的实际代码调用,如p{GoodChars}
或p{Class::Good_Characters}
。 你的语言如何处理这些可能值得关注。
沙箱
在Perl中,通过Safe
模块的沙盒隔离区可以控制命名空间的可见性。 其他语言提供类似的沙盒技术。 如果这些设备可用,则可能需要查看它们,因为它们专门设计用于有限执行不受信任的代码。
添加到tchrist的优秀答案:编写“Regular Expression”页面的Russ Cox也发布了代码! re2是一个C ++库,它保证了O(length_of_regex)运行时和可配置的内存使用限制。 它在Google中使用,以便您可以在Google代码搜索中键入正则表达式 - 这意味着它已经过测试。
是。
正则表达式可以用来执行DOS攻击。
没有简单的解决方案。
上一篇: Is there any way to put malicious code into a regular expression?