让用户输入正则表达式作为搜索输入是否安全?

信息安全 拒绝服务 正则表达式
2021-08-15 03:33:57

几天前我在商场里,我在指示面板上搜索了一家商店。

出于好奇,我试着搜索(.+)了一下,得到了商场里所有商店的名单,有点惊讶。

我读过一些关于邪恶正则表达式的文章,但似乎只有当攻击者同时控制搜索条目和搜索输入(正则表达式)时,才会发生这种攻击。

考虑到攻击者只能控制搜索输入,我们是否可以认为商场指示面板不受 DOS 影响?(撇开商店可能会被称为诸如 aaaaaaaaaaaa 之类的奇怪名称的可能性不谈。)

4个回答

在代码执行的风险方面,我会将接受用户提供的正则表达式与解析大多数类型的结构化用户输入(例如日期字符串或降价)进行比较。正则表达式比日期字符串或 markdown 复杂得多(尽管从不受信任的 markdown 安全地生成 html 有其自身的风险),因此代表了更大的利用空间,但基本原理是相同的:利用涉及发现解析的意外副作用/编译/匹配过程。

大多数正则表达式库都是成熟的,并且是许多语言的标准库的一部分,这是一个很好(但不确定)的指标,表明它没有导致代码执行的主要问题。
也就是说,它确实增加了你的攻击面,但做出衡量的决定接受相对较小的风险并不是不合理的。

拒绝服务攻击有点棘手。我认为大多数正则表达式库在设计时都考虑到了性能,但在其核心设计目标中并未将缓解故意慢速输入计算在内。从 DoS 角度接受用户提供的正则表达式的适当性更多地依赖于库。
例如,.NET 正则表达式库接受可用于缓解 DoS 攻击的超时。
RE2保证在时间上与输入大小成线性关系,如果您知道您的搜索语料库在某个合理的大小限制内,这可能是可以接受的。

在可用性绝对关键的情况下,或者您试图尽可能减少攻击面时,避免接受用户正则表达式是有意义的,但我认为这是一种可辩护的做法。

接受正则表达式的主要威胁在于您的正则表达式执行引擎,而不是接受正则表达式本身。我希望在任何实施良好的引擎中威胁都非常非常低。引擎不需要访问任何特权系统资源,并且只需要在直接提供给引擎的输入上运行逻辑。这意味着即使有人在解释器中发现了漏洞,可以造成的损害也应该是最小的。

总的来说,所有正则表达式的设计目的都是在一个值中寻找模式。只要您检查的值遵循适当的安全性,引擎本身就没有理由有权修改值。我将其归类为通常非常安全。

也就是说,我也只会在合理的情况下提供它。正则表达式很复杂,运行起来可能很耗时,并且在错误的地方使用可能会对安全上下文之外的应用程序产生一些不良影响,但在正确的用例中,它们非常强大且非常有价值。(我是一名软件架构师,经常使用正则表达式重构数十万行代码。)

正如其他答案所指出的那样,攻击向量很可能是正则表达式引擎。

虽然您会假设这些引擎非常成熟、强大且经过全面测试,但它确实发生在过去:

CVE-2010-1792 Apple Safari 和 iOS 中的任意代码执行。引用补丁说明

WebKit 处理正则表达式时存在内存损坏问题。访问恶意制作的网站可能会导致应用程序意外终止或任意代码执行。

但当然,可能存在缺陷的库的论点适用于所有内容——甚至是用户提供的 JPEG 文件

另一个方面,虽然不是固有的技术,但就是(.+)你提到的情况:产品应该允许任意数据检索吗?

问题是正则表达式引擎“回溯”。当您的正则表达式中有重复操作(例如 + 或 * )时,正则表达式引擎将尝试将其与尽可能多的输入字符串匹配。如果稍后匹配失败,那么它将回溯并尝试将您的重复内容与输入字符串的较小部分进行匹配。

多次重复操作会导致嵌套回溯,这会导致评估正则表达式的时间大量增加,尤其是在重复操作符嵌套的情况下。

https://www.regular-expressions.info/catastrophic.html