2023年1月21日
ReDosについて(OWASP)
https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
axiosのCVE-2021-3749は以下の正規表現が原因で発生していた。
入力に多大な空白を含む文字列を渡すと処理が遅くなる。
return str.replace(/^\s*/, '').replace(/\s*$/, '');
https://github.com/axios/axios/blob/5bc9ea24dda14e74def0b8ae9cdb3fa1a0c77773/lib/utils.js#L188
ローカルの検証用として、自分自身に攻撃する検証コードを用意した(huntrにて参考)
function build_blank (n) {
var ret = "1"
for (var i = 0; i < n; i++) {
ret += " "
}
return ret + "1";
}
function trim(str) {
return str.replace(/^\s*/, '').replace(/\s*$/, '');
}
var time = Date.now();
trim(build_blank(process.argv[2]));
var time_cost = Date.now() - time;
console.log("time_cost: " + time_cost)
検証コードに対して、文字列長を徐々に大きくしていった結果。
1万を超えたあたりから遅くなり始めていて、3万を超えると体感でも遅いと感じるくらいになる。
正規表現の書き方によっては処理に負担がかかることが確認できた。
修正後のコードは以下のようになっていた。
https://github.com/axios/axios/blob/main/lib/utils.js#L213
return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
このコードを修正して検証コードを実行してみた。
すっかり処理に負荷がかからないようになっていた。
正規表現の書き方でここまで処理に差が出るんだなぁ
様々などで使われている正規表現は問題ないのだろうか?の調査