
Long-Running-Action ヘッダーを介した saga ハイジャックApache Camel の脆弱性に対する実行可能な概念実証(PoC)再現ツールです。この脆弱性では、camel-core の SagaProcessor がすべての exchange において Long-Running-Action メッセージヘッダーから saga コーディネーターを選択していました。このヘッダー名には Camel プレフィックスが付いていないため、コンシューマーのヘッダーフィルターが除去する名前空間の外側に位置します。そのため、外部の送信者が受信メッセージにこのヘッダーを付与することで、その exchange が参加する saga を指定でき、自身のリクエストを他者が開始した長時間実行アクションに紐付けたり(あるいは、自身が開始していないアクションに補償処理を関連付けたり)することが可能でした。影響範囲は saga を実行しているデプロイメントに限定されますが、該当する場合には送信者が exchange の所属先 saga を制御できます(CWE-20)。
| ランタイム | ディレクトリ | スタック |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-spring-boot 4.22.0(影響あり、修正版 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-saga(Camel 4.22.0、影響あり、修正対照 CQ 3.40.0 / Camel 4.22.1) |
両モジュールとも、実際の camel-core SagaProcessor に対して影響を受ける動作と修正済みの動作の両方を実演します。
ドライバーは修正自体の回帰テスト(SagaHeaderCannotSelectCoordinatorTest)を模倣しています。saga ルート from("direct:…").saga().propagation(MANDATORY) を構築し、解決を要求されたすべての id を記録するインメモリ saga サービスでバックアップしたうえで、受信ヘッダー Long-Running-Action = a-saga-id-from-the-wire(外部送信者がワイヤ上に載せる id)を含む 1 つの exchange を送信します。判定基準は単純にどの saga id がサービスに到達するかです:
a-saga-id-from-the-wire が検索される — つまりメッセージがコーディネーターを選択したことになります。どちらのビルドでも MANDATORY exchange は最終的に失敗します(参加すべき実際の saga が存在しないため)。脆弱性はこの失敗ではなく、攻撃者が選択した id がコーディネーターの選択に使用されたこと自体にあり、だからこそ判定基準は結果ではなく検索を監視しているのです。
# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: wire id looked up = true; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85312-saga-header-hijack-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: wire id looked up = false; >>> Not exploited
# Camel Quarkus
cd camel-quarkus
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected (Camel 4.22.0): wire id looked up = true
docker compose down
# Patched control: CQ 3.40.0 ships Camel 4.22.1
mvn clean package -Dcamel-quarkus.version=3.40.0 -Dquarkus.platform.version=3.40.0
java -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: wire id looked up = false
| プロパティ | 値 |
|---|---|
| コンポーネント | camel-core (SagaProcessor.getCurrentSagaCoordinator) |
| CWE | CWE-20 (不適切な入力検証) |
| 重大度 | MEDIUM |
| 攻撃ベクトル | 外部の送信者が、saga EIP を実行するルートへの受信メッセージに、プレフィックスのない Long-Running-Action ヘッダーを付与して送信する |
| 影響 | 送信者が、エクスチェンジが参加する saga を指定できる — 他者の長時間実行アクションに接続したり、補償を誤って関連付けたりする |
| 影響を受けるバージョン | 4.0.0 から 4.18.5 未満、4.19.0 から 4.22.1 未満 |
| 修正済みバージョン | 4.18.5、4.22.1、4.23.0 |
| JIRA | CAMEL-24449 |
| クレジット | Claude Security Scan Tool |
アドバイザリ: https://camel.apache.org/security/CVE-2026-85312.html
影響を受ける Quarkus モジュールは CQ 3.39.0 (Camel 4.22.0) 上に構築されています。修正済みの制御は CQ 3.40.0 (Camel 4.22.1) です。
SagaProcessor は、saga サービスがそのようなプロトコルに参加することを表明している場合にのみ、Long-Running-Action ヘッダーを参照するようになりました。これは新しい CamelSagaService.isLongRunningActionHeaderSupported() を通じて行われます (デフォルトは false、LRA サービスはこれを true にオーバーライドします)。removeHeaders("*") を経ても存続する内部エクスチェンジ状態が引き続き saga id の通常の伝達手段であるため、メッセージが外部コーディネーターを実行しないサービスのコーディネーターを選択することはできなくなりました。
信頼境界において、信頼できない送信者からのメッセージを受け入れるすべてのコンシューマーで removeHeaders("Long-Running-Action") を使用してヘッダーを削除してください。
このリポジトリは教育および防御目的で公開されています。Apache Camel ユーザーが脆弱性を理解し、影響を受けているかどうかを確認し、アップグレードによって解決されることを検証できるようにするためです。デモは、インメモリの saga サービスを使用してインプロセスで saga ルートを実行します。「攻撃者」の saga id は無害なプレースホルダー文字列です。所有または運用していないシステムに対してこの資料を使用しないでください。