MongoDB $regex 查询和潜在漏洞利用
MongoDB $regex query and potential exploits
我们有一个 REST API 用于查询 MongoDB 中的记录。很简单,大致如下:
GET /api/items?q=foo
在开发过程中,允许使用正则表达式作为查询很方便 q
。我们只需将查询参数传递给 MongoDB $regex
运算符而不进行任何转义:
db.getCollection('items').find({ name: { $regex: req.query.q, $options: 'i' } });
因此,我们有一种非常灵活方便的方式来查询我们的数据。现在,事情变得“严重”,即接近生产,我在问自己安全隐患。有人可以使用昂贵的回溯发送“DoS”查询吗?
我的破坏力可能不足以想到这样的查询,所以我在网上搜索了一下,发现了这篇非常有趣的文章,其中提到了几种攻击:The Explosive Quantifier Trap.
抛开上述页面上提到的查询的行为远非预期的“灾难性”这一事实(既不在 MongoDB 查询中,也不在 regex101.com 等在线工具中),我还是想知道:
- 这是一个真正的问题还是我在追逐不存在的威胁?
- 我们是否应该完全摆脱正则表达式参数?
- MongoDB是否有任何机制(即超时)来防止通过恶意正则表达式进行 DoS 攻击? (顺便说一下:我们 运行 在 Node.js 环境中)
- 是否有任何库可以在发出查询之前检测此类攻击?
我个人的直觉告诉我:别费心了。但话又说回来,如果你仍然这样做或者甚至必须这样做,那么这里有一些关于如何处理这个要求的建议:
- 您可以定义查询可以 运行 使用 maxTimeMS() 的最长时间。
- 您可以尝试清理正则表达式输入,但我怀疑是否有库可以帮助您解决可能很长 运行ning 复杂查询的无穷无尽的变化。限制正则表达式的长度也可能有所帮助,但另一方面可能会破坏允许用户使用任意过滤器方便地搜索的目的。
- 您可以提供更加结构化的查询输入,例如只允许用户输入单个字母数字文本,然后您可以将其包装在服务器端的正则表达式中以允许例如"starts-with"、"contains" 或 "ends-with" 查询或其他内容。
- 您可以只允许每个用户(会话?ip?)一个单独的并行查询,这可能对抵御致命的 DoS 攻击有一点帮助,但肯定不会对付分布式攻击...或者您甚至可以只允许一个单独的并行调用整个系统中的该端点。
我们有一个 REST API 用于查询 MongoDB 中的记录。很简单,大致如下:
GET /api/items?q=foo
在开发过程中,允许使用正则表达式作为查询很方便 q
。我们只需将查询参数传递给 MongoDB $regex
运算符而不进行任何转义:
db.getCollection('items').find({ name: { $regex: req.query.q, $options: 'i' } });
因此,我们有一种非常灵活方便的方式来查询我们的数据。现在,事情变得“严重”,即接近生产,我在问自己安全隐患。有人可以使用昂贵的回溯发送“DoS”查询吗?
我的破坏力可能不足以想到这样的查询,所以我在网上搜索了一下,发现了这篇非常有趣的文章,其中提到了几种攻击:The Explosive Quantifier Trap.
抛开上述页面上提到的查询的行为远非预期的“灾难性”这一事实(既不在 MongoDB 查询中,也不在 regex101.com 等在线工具中),我还是想知道:
- 这是一个真正的问题还是我在追逐不存在的威胁?
- 我们是否应该完全摆脱正则表达式参数?
- MongoDB是否有任何机制(即超时)来防止通过恶意正则表达式进行 DoS 攻击? (顺便说一下:我们 运行 在 Node.js 环境中)
- 是否有任何库可以在发出查询之前检测此类攻击?
我个人的直觉告诉我:别费心了。但话又说回来,如果你仍然这样做或者甚至必须这样做,那么这里有一些关于如何处理这个要求的建议:
- 您可以定义查询可以 运行 使用 maxTimeMS() 的最长时间。
- 您可以尝试清理正则表达式输入,但我怀疑是否有库可以帮助您解决可能很长 运行ning 复杂查询的无穷无尽的变化。限制正则表达式的长度也可能有所帮助,但另一方面可能会破坏允许用户使用任意过滤器方便地搜索的目的。
- 您可以提供更加结构化的查询输入,例如只允许用户输入单个字母数字文本,然后您可以将其包装在服务器端的正则表达式中以允许例如"starts-with"、"contains" 或 "ends-with" 查询或其他内容。
- 您可以只允许每个用户(会话?ip?)一个单独的并行查询,这可能对抵御致命的 DoS 攻击有一点帮助,但肯定不会对付分布式攻击...或者您甚至可以只允许一个单独的并行调用整个系统中的该端点。