Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于 Node.js 正则表达式拒绝服务攻击 #13

Open
luokuning opened this issue Mar 4, 2019 · 0 comments
Open

关于 Node.js 正则表达式拒绝服务攻击 #13

luokuning opened this issue Mar 4, 2019 · 0 comments
Labels

Comments

@luokuning
Copy link
Owner

luokuning commented Mar 4, 2019

从 npm audit 说起

今天尝试用 npm audit 在项目里跑了一下,发现了很多类似下面的错误:

image

如果你还不清楚 npm audit 是做什么的,可以参考官方文档。简单来说 npm audit 会对项目的依赖包进行安全扫描,并且列出存在的可能遭受攻击的安全隐患,比如上面截图中的信息就是一个潜在的被攻击点。

Regular Expression Denial of Service (ReDoS)

图片第一行显示的 Regular Expression Denial of Service 成功引起了我的注意。Denial of Service 我们都知道,拒绝服务攻击,以一种简单暴力的方式消耗被攻击者的资源,让其服务到达不可用的地步,比如常见的 DDoS。那么 Regular Expression Denial of Service (以下简称 ReDoS) 通过字面意思理解应该就是:正则表达式拒绝服务攻击。

正则表达式的匹配通常是比较耗费计算性能的,尤其是当正则表达式中包含复杂的子表达式的重复匹配、或者重复匹配的简单子表达式也可能匹配另一个子表达式的时候。当一个正则表达式存在这些问题的时候,一些用户的输入可能会导致匹配运行效率非常低下,从而引发 DoS (因为计算资源可能被耗尽)。

Node.js 中的 ReDoS

说了这么多,也许不如一个例子能够把我的意思表达的更清楚:

image

测试环境:MacBook Pro (Retina, 15-inch, Mid 2015), 2.2 GHz Intel Core i7

上面正则表达式看起来非常简单,但是存在我们上面说的可能导致匹配效率低下的问题。可以看到这个简单的匹配耗时大约 5 秒钟,对于 Node.js 这种基于 event loop 的单进程服务器来说是不可接受的。

解决办法

尽量使用社区开源的正则表达式。如果你正在做一些常规的字符串校验,比如邮件、电话号码的匹配,那么可以尝试 validator.js

如果需要自己编写正则表达式,可以使用 safe-regex 这样的工具来校验自己的正则表达式是否有潜在的问题,也可以使用 regex101 在线进行检验 (regex101 功能十分强大,界面也很清新,另外还提供了 debugger 功能),比如上面的这个例子在 regex101 里会被检测到有 “灾难性的回溯”(Catastrophic backtracking) 问题:

image

附录

出于好奇,用 Rust 写了跟上面 Node.js 例子中的正则表达式,下面是执行的结果:

image

Rust 好像对于正则表达式这些潜在的性能问题有一些预防的解决方案 (只调用回溯引擎的混合解决方案),具体我也不是太了解,有兴趣的小伙伴可以自行查资料。不过 Rust 确实是非常快的,真的要抽空好好学习 Rust 咯,后面用得到的地方还是很多的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant