ReDos攻撃
Regular expression Denial of Service
メールアドレスのvalidationなど、内部で正規表現を使っている箇所に対して、処理時間が多くかかる入力を与えることでサービス停止などの障害を起こす
validation libraryとか使っていると汎用的な正規表現を組みわせて使いがちだけど微妙な気がしてきたなmrsekut.icon
例えば、「全角を含む数値ができて、範囲は0~10000」というようなルールの場合
「(全角含む)数値全て」「正数」「整数」「上限は10000」を別々に書いて、個々でvalidation errorを用意するように実装することが多い
「数値を入力してください」
「0より大きい数値で入力してください」
という風に。
しかし、この最初の汎用的な「(全角含む)数値全て」のルールは
^[-ー]?[0-90-9]*\.?[0-90-9]+$とかだけど、
これは上限がないため、ReDoS攻撃が可能である
入力が5桁を超えた時点で、「上限は10000です」のエラーメッセージは表示されるが、ユーザーはそれ以上の数値を入力可能である
だから、ここにめちゃくちゃ大きい数値を入力すれば攻撃が実現できてしまう
より安全にするためには、この「数値全て」のルールにも「上限5桁{5}」というルールも含めれば対策できるはず
実装にも依るけど、clientで行うform validationの場合は、ただ単にブラウザがクラッシュするだけかmrsekut.icon
HTTP requestとかのqueryのvalidationで正規表現を使っているとReDoS攻撃できてしまうのかmrsekut.icon
具体例
(a+)+b
console.logで、'aaaaa'.match(/^(a+)+b/)をaを増やしていくとクラッシュしたmrsekut.icon
(a|.)+b
a.+b.+c
具体例
以下は脆弱なemailの正規表現
^([A-Z0-9_+-]+\.?)*[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$
以下は修正後のemailの正規表現
^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$
どうすれば改善されるのか
(libraryの問題ではなく)自分の書く正規表現の問題
例えば.+aではなくて、上限を明示して.{5}aと書くなど
どう対策する?
web上で試せる
攻撃例も見れる