ReDoS攻撃について
ReDoS(Regular Expression Denial of Service)攻撃は、正規表現の処理において計算量が急激に増加するケースを悪用して、システムのリソースを過剰に消費させることで、サービス拒否(DoS)状態を引き起こす攻撃です。特に、バックトラッキングが多発する複雑な正規表現や、非効率的な正規表現を使用している場合に、この攻撃が可能になります。
脆弱なコード:
<?php
$input = $_GET['input'];
if (preg_match('/^(a+)+$/', $input)) {
echo "Match found!";
} else {
echo "No match.";
}
?>
攻撃手法:
このコードは、a
の連続する文字列をチェックするために正規表現を使用していますが、入力として大量のa
と無関係な文字を含む文字列(例: aaaaaaaaaaaaaaaaaaaaX
)を送信することで、正規表現の処理が長時間にわたり続き、サーバーが応答しなくなる可能性があります。
脆弱なコード:
import re
input_string = input("Enter a string: ")
pattern = re.compile(r'^(a+)+$')
if pattern.match(input_string):
print("Match found!")
else:
print("No match.")
攻撃手法:
Pythonでも同様に、aaaaaaaaaaaaaaaaaaaaX
のような入力を与えることで、正規表現の処理時間が劇的に増加し、システムリソースを大量に消費します。
re
モジュールは、バックトラックが多く発生する正規表現に対して脆弱です。特に、入力の長さが増加するにつれて、処理時間が急激に増加する正規表現が存在する場合、ReDoS攻撃のリスクが高まります。re
モジュールにいくつかのパフォーマンス改善が行われましたが、根本的にはReDoS攻撃に対する完全な防御策が導入されているわけではありません。re
モジュールのパフォーマンスがさらに改善されていますが、それでも複雑な正規表現に対するReDoS攻撃に対して完全に安全とは言えません。脆弱なコード:
const input = req.query.input;
const regex = /^(a+)+$/;
if (regex.test(input)) {
res.send("Match found!");
} else {
res.send("No match.");
}
攻撃手法: Node.jsでも、複雑な正規表現に対して攻撃者が巧妙に構成された入力を送信することで、CPU使用率が高まり、サービスが停止する可能性があります。
脆弱なコード:
import java.util.regex.*;
public class ReDoSExample {
public static void main(String[] args) {
String input = args[0];
Pattern pattern = Pattern.compile("^(a+)+$");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Match found!");
} else {
System.out.println("No match.");
}
}
}
攻撃手法:
Javaでも、複雑な正規表現に対して攻撃者が膨大な入力(例: aaaaaaaaaaaaaaaaaaaaX
)を提供することで、正規表現の評価が非常に遅くなり、システムが応答しなくなる可能性があります。
^(a+)+$
の代わりに、^a+$
のようなよりシンプルな正規表現を使用する。java.util.regex.Matcher
で正規表現のタイムアウトを実装することが可能です。まとめ: ReDoS攻撃は、正規表現の非効率的な処理を悪用することでサービス拒否状態を引き起こす攻撃です。複雑な正規表現を最適化することや、入力制限、タイムアウト設定、ライブラリのアップデートを通じて、この脆弱性を効果的に防ぐことが可能です。各言語に共通する問題であるため、特に注意を払い、対策を講じることが求められます。