我想在我的公共网页上添加正则表达式搜索功能。除了对输出进行HTML编码之外,我还需要采取其他措施来防止恶意用户输入吗?
解决正反问题的人们淹没了Google搜索-使用正则表达式检测恶意输入-我对此并不感兴趣。在我的情况下,用户输入是一个正则表达式。
我将在.NET(C#)中使用Regex库。
我想在我的公共网页上添加正则表达式搜索功能。除了对输出进行HTML编码之外,我还需要采取其他措施来防止恶意用户输入吗?
解决正反问题的人们淹没了Google搜索-使用正则表达式检测恶意输入-我对此并不感兴趣。在我的情况下,用户输入是一个正则表达式。
我将在.NET(C#)中使用Regex库。
Answers:
正则表达式最常见的问题是通过呈指数级甚至超指数级的病理模式进行的拒绝服务攻击!—因此似乎需要永远解决。这些可能只显示在特定的输入数据上,但是通常可以创建一个无关紧要的数据。
这些是哪一种将在某种程度上取决于您所使用的regex编译器的智能程度,因为其中有些可以在编译时检测到。实现递归的正则表达式编译器通常具有内置的递归深度计数器,用于检查非递归。
拉斯·考克斯(Russ Cox)在2007年出色的关于正则表达式匹配的论文可以既简单又快速(但是在Java,Perl,PHP,Python,Ruby等方面却很慢)谈论了大多数现代NFA的方式,这些似乎都源于Henry Spencer的代码会遭受严重的性能下降,但是汤普森(Thompson)风格的NFA没有此类问题。
如果您只接受DFA可以解决的模式,则可以将其编译成这样,它们将运行得更快,甚至可能更快。但是,这需要时间。Cox论文提到了这种方法及其附带的问题。一切都归结为经典的时空权衡。
使用DFA,您将花费更多的时间来构建它(并分配更多的状态),而使用NFA时,您将花费更多的时间来执行它,因为它可以同时处于多个状态,并且回溯可以吃掉您的午餐和CPU。
解决这些模式的最合理的方法可能是在竞赛中随着宇宙的热死而逐渐消失,这是用计时器包装它们,该计时器可以有效地放置执行它们所允许的最大时间。通常,这将比大多数HTTP服务器提供的默认超时小很多。
有多种方法可以实现这些功能,从alarm(N)
C级的简单形式到某种try {}
类型的catch警报类型的异常阻止,一直到产生一个新线程,该线程是专门建立在其中的具有时间限制的。
在允许代码标注的正则表达式语言中,应提供一些机制来允许或禁止您要编译的字符串中的代码标注。即使代码标注仅用于使用您所使用的语言编写代码,也应限制它们;他们不必调用外部代码,尽管如果可以,您将遇到更大的问题。
例如,在Perl中,除非use re "eval";
在当前作用域中处于活动状态的特殊的词法范围编译指示有效,否则不能在通过字符串插值创建的正则表达式中使用代码标注(因为这样,因为它们是在运行时编译的)。
这样,没有人可以潜入代码标注来运行诸如之类的系统程序rm -rf *
。由于代码标注对安全性非常敏感,因此默认情况下,Perl会在所有插值字符串上将其禁用,并且您必须竭尽全力来重新启用它们。
仍然与Unicode的样式属性一个更安全的敏感问题-像\pM
,\p{Pd}
,\p{Pattern_Syntax}
,或者\p{Script=Greek}
-这可能会存在一些正则表达式的编译器支持该符号。
问题在于,其中某些属性集是用户可扩展的。这意味着您可以拥有自定义属性,这些属性是对某些特定名称空间(例如\p{GoodChars}
或)中命名函数的实际代码标注\p{Class::Good_Characters}
。您的语言如何处理这些问题可能值得研究。
在Perl中,通过Safe
模块的沙盒隔离区将控制名称空间的可见性。其他语言也提供类似的沙盒技术。如果有可用的此类设备,则可能需要对其进行研究,因为它们是专门为有限执行不受信任的代码而设计的。
添加到tchrist的出色答案中:编写“正则表达式”页面的同一Russ Cox也发布了代码!re2是一个C ++库,可确保O(length_of_regex)运行时和可配置的内存使用限制。它在Google中使用,因此您可以在Google代码搜索中输入正则表达式-这意味着它已经过实战测试。
是。
正则表达式可用于执行DOS攻击。
没有简单的解决方案。
您需要阅读以下文章:
不安全的上下文切换:接种正则表达式以提高生存能力 本文更多地讨论了正则表达式引擎(例如PCRE)可能出现的问题,但它可以帮助您了解要面对的问题。
您不仅要担心匹配本身,而且还要担心如何进行匹配。例如,如果您的输入在进入正则表达式引擎的过程中经历了某种评估阶段或命令替换,则可能在模式内部执行了代码。或者,如果您的正则表达式语法允许使用嵌入式命令,则也必须注意这一点。由于您没有在问题中指定语言,因此很难确定所有安全含义是什么。
Microsoft最近发布的SDL RegEx模糊测试工具是测试RegEx安全问题的一种好方法(至少对于Windows是这样)。这可以帮助避免RegEx构造上的病理错误。