Apache Tomcatで脆弱性8件、Importantは認証回避とレスポンス混入の3件
目次
TL;DR
影響 Tomcat 9・10.1・11で8件。Importantは、JNDIRealmでGSSAPI以外のSASLを設定したときにパスワードなしで認証が通る問題、HTTP/2の非同期処理で別の利用者とリクエスト・レスポンスが入れ替わる問題、AJPで前のレスポンスが次のリクエストへ漏れる問題(11だけ)の3件
対応 9.0.123、10.1.61、11.0.27へ更新。どれも10月12日にリリース済み
条件 Importantの3件はどれも特定の設定で起きる。初期設定のserver.xmlでは、HTTP/2の設定を含む接続の受け口(コネクター)とAJPのコネクターはコメントアウトされている
2026年10月20日、Apache Tomcatのセキュリティページに、9.x・10.1.x・11.xの脆弱性8件が載った(Apache Tomcat 11.x、10.x、9.x)。
修正は8日前の10月12日に出た9.0.123、10.1.61、11.0.27にすでに含まれていて、Tomcatが付けた深刻度はImportantが3件、Lowが5件だった。
TomcatはJavaのWebアプリ(Servlet)を動かすサーバーで、Spring Bootの標準構成でも組み込みで使われている。
公開された8件
| CVE | 内容 | 深刻度 |
|---|---|---|
| CVE-2026-101296 | JNDIRealmでGSSAPI以外のSASLを設定すると、正しいパスワードなしで認証が通る | Important |
| CVE-2026-101356 | HTTP/2の非同期処理でエラーが起きたあと、別の利用者とリクエスト・レスポンスが入れ替わる | Important |
| CVE-2026-103119 | AJPで大きな非ブロッキング書き込みのレスポンスが、同じ接続の次のリクエストへ分かれて送られる | Important |
| CVE-2026-93446 | TLS 1.3の接続がときどき失敗する | Low |
| CVE-2026-88041 | HTTP/2で前のリクエストのトレーラー(本文のあとに送るヘッダー)が次のリクエストに漏れる | Low |
| CVE-2026-74049 | Jasper(TomcatのJSP処理系)の <c:redirect> が、リダイレクト後もページの残りを処理する | Low |
| CVE-2026-74048 | OpenSSL-FFMでFIPS(米国政府の暗号モジュールの基準)モードの有効化に失敗しても、FIPSなしのまま起動する | Low |
| CVE-2026-80353 | APRコネクター(ネイティブライブラリを使う接続処理)でUnixドメインソケットを作るときの競合で、権限のないローカルユーザーが接続できる | Low |
影響する版は系列ごとに違うので、各系列のセキュリティページに書かれた範囲を次の表に載せ、その系列のページにない件は - にした。
9.0.0.M1 や 11.0.0-M1 のMは、正式版の前に出るマイルストーン版を指す。
| CVE | 9.0.x | 10.1.x | 11.0.x |
|---|---|---|---|
| CVE-2026-101296 | 9.0.0.M1〜9.0.122 | 10.1.0-M1〜10.1.60 | 11.0.0-M1〜11.0.26 |
| CVE-2026-101356 | 9.0.118〜9.0.122 | 10.1.55〜10.1.60 | 11.0.22〜11.0.26 |
| CVE-2026-103119 | - | - | 11.0.0-M25〜11.0.26 |
| CVE-2026-93446 | 9.0.90〜9.0.122 | 10.1.25〜10.1.60 | 11.0.0-M21〜11.0.26 |
| CVE-2026-88041 | 9.0.92〜9.0.122 | 10.1.27〜10.1.60 | 11.0.0-M23〜11.0.26 |
| CVE-2026-74049 | 9.0.0.M1〜9.0.122 | 10.1.0-M1〜10.1.60 | 11.0.0-M1〜11.0.26 |
| CVE-2026-74048 | 9.0.92〜9.0.122 | 10.1.22〜10.1.60 | 11.0.0-M14〜11.0.26 |
| CVE-2026-80353 | 9.0.47〜9.0.122 | - | - |
Unixドメインソケットの権限設定での同じ競合は、以前にCVE-2026-65183として修正されていた。
その修正がAPRコネクターを対象にしていなかったための追加修正がCVE-2026-80353で、9.xのページにだけ載っている。
JNDIRealmの認証回避(CVE-2026-101296)
Realmは、Tomcatがユーザー名・パスワード・ロール(権限のグループ)を照合する仕組みで、JNDIRealmはこの照合をLDAPのディレクトリへの問い合わせで行う。
userPassword 属性を指定しない設定では、JNDIRealmはディレクトリ上のユーザーの名前(DN)と入力されたパスワードでLDAPにログインし、成功したら認証済みとして扱う(The Realm Component)。
LDAPではこのログインをbindと呼び、ドキュメントでは、DNとパスワードをそのまま送るsimple bindを使うと書かれている。
authentication 属性には、none、simple、strong のほかに、SASL(LDAPなどで使う認証方式の枠組み)の方式名のような、プロバイダー固有の値も指定できる。
修正前のTomcatは、Kerberosを使う GSSAPI が指定されているときだけ、パスワードを確かめるbindの間この設定を外していた。
それ以外のSASLの方式名を指定していると、その方式のままbindしていて、アドバイザリによると、この設定で攻撃者が正しいパスワードなしに認証できた。
修正では、パスワードを確かめるbindで方式を必ず simple にし、終わったら元の設定に戻すようにした(e43453fc)。
影響する版は9.0、10.1、11.0の各系列のほぼすべてだが、JNDIRealmを使っていて authentication に GSSAPI 以外のSASLの方式名を入れている構成でなければ当てはまらない。
server.xmlやcontext.xmlで org.apache.catalina.realm.JNDIRealm の <Realm> を探し、authentication の値を確かめる。
HTTP/2の非同期処理でのリクエスト・レスポンスの入れ替わり(CVE-2026-101356)
Servletの非同期処理では、startAsync() でリクエストを受けたスレッドを手放し、時間のかかる処理が終わってから別のスレッドでレスポンスを返す。
Tomcatはリクエストやレスポンスのオブジェクトを使い回していて、アドバイザリによると、HTTP/2で非同期のServletを処理しているときにエラーが起きると、このオブジェクトの再利用を誤ることがあり、別の利用者との間でリクエストやレスポンスが入れ替わる。
修正は1行で、非同期処理の状態を管理するクラスがエラー状態かどうかを判定するときに、ERROR だけでなく MUST_ERROR の状態もエラーとして扱うようにした(1dc6aa15)。
コミットに付いた変更履歴には、一部のエラーで予期しない IllegalStateException が起きる、非同期のエラー処理の抜けを直したと書かれている。
9.0.118以降、10.1.55以降、11.0.22以降と比較的新しい版にだけ影響があり、TomcatがHTTP/2を直接受けていて、非同期のServletを使っている場合に当てはまる。
11.0.27の初期設定のserver.xmlでは、HTTP/2を有効にする Http2Protocol を含む8443番のコネクターはコメントアウトされている(conf/server.xml)。
利用者からの接続を受けてTomcatへ中継するリバースプロキシ(nginxなど)でHTTP/2を受け、TomcatへはHTTP/1.1で転送している構成なら、Tomcat側ではHTTP/2を処理しない。
AJPで前のレスポンスが次のリクエストへ漏れる問題(CVE-2026-103119)
Apache httpdの mod_jk や mod_proxy_ajp は、AJPというプロトコルでTomcatへリクエストを転送する。
Servletの出力には非ブロッキングの方式もあり、WriteListener を登録して、ソケットが送れる状態のときにだけデータを書き込む。
アドバイザリによると、buffer under-readと呼ばれるバッファー処理の不具合が原因で、AJPで大きなレスポンス本文を非ブロッキングで書き込むと、今のリクエストと、同じ接続で次に受けたリクエストに本文が分かれて送られることがある。
多くの場合は2つ目のリクエストが失敗するだけだが、1つ目のレスポンスのデータが2つ目に漏れる可能性もあるという。
修正コミットは、Servlet仕様の「Content-Length ぶん書き終えたらレスポンスを閉じる」処理を変えている(f13748ba)。
修正前は、書いたバイト数が Content-Length に達した時点でレスポンスを閉じていた。
修正後は、非ブロッキングの書き込みに限り、達した時点では閉じないで、Content-Length を超えて書こうとした時点で閉じる。
変更履歴によると、ちょうど Content-Length ぶん書く非ブロッキングの書き込みを、非ブロッキングのまま終わらせてから閉じるための変更だという。
影響する版は11.0.0-M25から11.0.26で、9.xと10.1.xのページには載っていない。
AJPのコネクターは9.0.31より前は初期状態で有効だったが、今の初期設定のserver.xmlではコメントアウトされている。
httpdとAJPでつないでいないTomcat 11や、9.x・10.1.xは、この件の対象にならない。
修正版への更新
修正版は10月12日にリリースされている(Apache Tomcat)。
| 系列 | 修正版 | 必要なJava |
|---|---|---|
| Tomcat 11.0.x | 11.0.27 | 17以降 |
| Tomcat 10.1.x | 10.1.61 | 11以降 |
| Tomcat 9.0.x | 9.0.123 | 8以降 |
Tomcatを単体で入れている場合は、bin/version.sh(Windowsは bin\version.bat)で今の版を確かめ、同じ系列の修正版に入れ替える。
サポート中の系列は11.0.x、10.1.x、9.0.xで、8.5.xは2024年3月31日に、10.0.xは2022年10月31日にサポートが終わっている(Which version do I want?)。
サポートが終わった系列には修正版が出ないので、使っているならサポート中の系列への移行が必要になる。
Spring Bootなど組み込みのTomcatを使うアプリは、Tomcatの版がフレームワークの依存関係で決まる。
mvn dependency:tree や gradle dependencies で tomcat-embed-core の実際の版を出して確かめる(Spring BootでRequest SmugglingとRequest Splittingを取り違えない)。
Spring Bootの依存関係管理では、Tomcatの版を tomcat.version プロパティで上書きできる(Spring Boot Dependency Versions Properties)。