logo科技微讯

ReDoS:Regex DoS 攻击

作者:科技微讯
日期:2023-06-07
📝 笔记

DoS 是 denial of service 的缩写,意思是服务不可用。DoS 攻击是从攻击的目的或意图这个角度来命名的,意思是为了让对方的服务不可用而发起的攻击。

一个很出名的词是 DDoS,它是 distributed denial of service 的缩写,意思是分布式的 DoS 攻击。

这里说的是 ReDoS,意思是基于 Regex 发起的攻击。为了方便理解,我让 ChatGPT 给出一个 ReDoS 攻击的例子,当然我有所改动:

import timespand from "time-span";
const end = timespand();
const input = "a".repeat(30) + "b";
const regex = /^(a+)+$/;
const match = regex.test(input);
console.log(match); //结果是 false
console.log(end()); //在我的 Apple M1 Pro 电脑上耗时 35s

上面这段代码,在我的 Apple M1 Pro 电脑上执行,耗时长达 35 秒。

假设你的应用有一个输入框,你的后端使用 /^(a+)+$/ 对用户的输入进行正则处理,然后攻击者输入了 aaa...(一共30个a)...aaab ,那攻击者就会让你的服务卡住 35 秒。

如果攻击者输入了更多的 a,比如 10000 个,那你的后端可能会卡住很长很长时间,导致无法向正常用户提供服务,于是攻击者达成了他的 ReDoS 攻击。

所以作为开发者,要注意小心写书你的正则法则,像例子中的 nested repetition operators 是需要避免的,例如可以改为 /^(a{1,10})+$/,确保了 a 的数量不能超过 10 个。

另一种应对方法是,当发现正则处理耗时太久时,就直接让它超时:sindresorhus/super-regex

一种更好的做法是使用 uhop/node-re2 创建正则对象,不使用 Node.js 内置的正则引擎。

把例子中的 const regex = /^(a+)+$/ 改为以下代码就没问题了:

import RE2 from "re2";
const regex = new RE2(/^(a+)+$/);

类似的库还有 re2js

donation赞赏
thumbsup0
thumbsdown0
暂无评论