
CVE-2026-40047の再現ツール: Apache Camel camel-docling CLI引数インジェクション / パストラバーサル
このプロジェクトは、Apache Camel の camel-docling コンポーネントにおける CLI 引数インジェクションおよびパストラバーサルの脆弱性 (CVE-2026-40047) を実証するものです。DoclingProducer はメッセージヘッダーから外部の docling コマンドラインツールの呼び出しを構築しますが、CamelDoclingCustomArguments ヘッダーを介して指定されるカスタム引数は、不十分な検証 (ブラックリストとリテラル ../ チェック) のみで追加されるため、これらのヘッダーを操作できる攻撃者は任意の docling CLI フラグやトラバーサルを含むパス値をサブプロセスに注入できます。
アドバイザリ: https://camel.apache.org/security/CVE-2026-40047.html
| プロパティ | 値 |
|---|---|
| コンポーネント | camel-docling |
| 影響を受けるクラス | org.apache.camel.component.docling.DoclingProducer (addCustomArguments / validateCustomArguments) |
| 根本原因 | CamelDoclingCustomArguments (List) を docling CLI 引数に、弱いブラックリスト + リテラル ../ チェックのみで追加している |
| CWE | CWE-88 (引数インジェクション) / CWE-22 (パストラバーサル) |
| 影響 | 任意の意図しない docling CLI フラグおよびディレクトリ外のパス値を外部ツールに注入可能。OS コマンドインジェクションではない (リスト形式の ProcessBuilder、シェル未使用)。 |
| 影響を受けるバージョン | 4.15.0 から 4.18.3 未満 |
| 修正バージョン | 4.18.3, 4.19.0 |
| JIRA | CAMEL-23212 |
| 報告者 | Andrea Cosentino (Apache Software Foundation) |
DoclingProducer は docling の呼び出しを組み立て、java.lang.ProcessBuilder (リスト形式 — シェルは使用しない) を介して実行します。CamelDoclingCustomArguments ヘッダーからのカスタム CLI 引数がコマンドに追加されます:
// DoclingProducer.addCustomArguments(...) - 影響を受けるバージョン
List<String> customArgs = exchange.getIn().getHeader(DoclingHeaders.CUSTOM_ARGUMENTS, List.class);
if (customArgs != null && !customArgs.isEmpty()) {
validateCustomArguments(customArgs); // ブラックリスト + リテラル "../" チェック (弱い)
command.addAll(customArgs);
}
影響を受けるバージョンでは、validateCustomArguments は禁止フラグのブラックリストに依存し、パス値に対してはリテラル ../ を含む場合のみ拒否していました。その結果:
docling に渡されます。../ を含まないトラバーサルパス値 (絶対パスや正規化されたシーケンス) は検出されません。Camel が docling の呼び出しを構築するため、これらの値を制限する責任はコンポーネントにあります。修正 (CAMEL-23212) では、ブラックリストを厳格なホワイトリストに置き換え、プロデューサ管理のフラグ (--output/-o) やシェルメタキャラクタ (多層防御) を拒否し、パス値は Path.normalize() で正規化してから検証します。
呼び出しは
ProcessBuilderのリスト形式を使用するため、シェルが値を解釈することはありません。シェルメタキャラクタによる OS コマンドインジェクションは不可能であり、修正におけるメタキャラクタ拒否は多層防御です。
from("direct:convert")
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
docling は外部ツールです。この再現ツールは (コンテナ内の PATH 上に) スタブ docling を同梱しており、受信した argv をログに記録し、マークダウンファイルを書き戻すため、注入された引数が HTTP 応答および /tmp/docling-invocations.log で確認できます。すべて Docker イメージ (アプリ + スタブ) 内で実行されるため、実際の docling のインストールは不要です。
docling の実行用)mvn clean package -DskipTests
docker compose up -d --build
curl http://localhost:8080/exploit/normal
# スタブ docling が受け取る: docling --to md --ocr-lang en --output <tmp> /tmp/input.txt
curl "http://localhost:8080/exploit/attack"
# CamelDoclingCustomArguments = [--injected-by-attacker, arbitrary-value] を注入
# -> スタブ docling が受け取る:
# docling --injected-by-attacker arbitrary-value --to md --ocr-lang en --output <tmp> /tmp/input.txt
# リテラル "../" を含まないパス値 (絶対パス) も通過する:
curl "http://localhost:8080/exploit/attack?flag=--artifacts-path&value=/etc/attacker-controlled"
影響を受けるバージョン (この再現ツールは 4.18.2 に固定) では、ルートは 成功 し、注入された引数がサブプロセスに到達します。修正バージョン (4.18.3 / 4.19.0) では、ホワイトリストが --injected-by-attacker を IllegalArgumentException で拒否し、ルートは失敗します。
docker compose down
CamelDoclingCustomArguments (またはパスを含むヘッダー) に転送する Camel ルートが存在する。4.18.3 / 4.19.0 にアップグレードしてください。修正では、認識された docling フラグの厳格なホワイトリストを使用し、プロデューサ管理のフラグとシェルメタキャラクタを拒否し、パス値を Path.normalize() で正規化してから検証します。
アップグレードまでの間:
CamelDoclingCustomArguments やパスを含むヘッダーにマッピングしないでください。docling: プロデューサの前に Camel 内部ヘッダー (removeHeaders("Camel*")) を削除してください。CVE-2026-40047/
├── pom.xml
├── Dockerfile # アプリ + PATH 上のスタブ 'docling'
├── docker-compose.yml
├── docling-stub.sh # スタブ 'docling' (argv をログ出力、マークダウンを書き込み)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── DoclingRoute.java # from(direct:convert).to(docling:convert)
│ └── ExploitController.java # CamelDoclingCustomArguments を注入
└── resources/
└── application.properties
この再現ツールは、公開され修正済みの脆弱性に対するセキュリティ研究および許可されたテスト専用として提供されます。明示的な許可なくシステムに対して使用しないでください。