再現してみました正規表現によるサービス拒否攻撃(a+)+
regexpを使用し、 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
(大量のa
)入力を jshell で実行します。
Pattern.compile("(a+)+")
.matcher("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!")
.matches()
しかし、これは私が試すたびにかなり早く完了します。Java の正規表現の実装は他のものと異なるのでしょうか? または、リンクされた Wikipedia ページが間違っているのでしょうか?
(ちなみに、私は Java 11 を使用しています)
編集: Java のバージョンに関連しているようです。Java 8 で試したところ、ハングしましたが、Java 9 と 11 ではすぐに動作します。これらのバージョン間で何が変更されて、それが影響したのでしょうか? Java では現在、すべての正規表現が安全ですか?
正規表現の実装を変更した特定の Java JEP はありますか? 新しい Java ではどのような種類の正規表現が依然として問題となるのかを知りたいです。
ベストアンサー1
記事によるとRSPEC-2631ReDoS 問題は Java 9 以降で対処されています。
OpenJDK 9+ などの Java ランタイムは、正規表現評価の実装に追加の保護を加えることでこの問題を軽減しています。これらのランタイムでは、上記の例は脆弱ではありません。