## Summary
A distinct bypass was confirmed for the Apache Camel `camel-docling` fix. The fixed 4.18.3 and latest-tested 4.21.0 code correctly rejects unknown attacker-controlled values in `CamelDoclingCustomArguments`, but the same `DoclingProducer` command-building path still appends the separate path-bearing `CamelDoclingOutputFilePath` exchange header as the `docling --output` value without applying the new path-normalization/traversal checks. A Camel HTTP route that maps an untrusted header (`X-Out`) into `CamelDoclingOutputFilePath` can therefore pass `SAFE_OUTPUT_DIR/../escaped-output` to the `docling` subprocess on fixed releases, causing output to be written outside the intended safe directory.

## Fix Coverage / Assumptions
The original fix relies on the invariant that attacker-controlled custom docling CLI input enters through `CamelDoclingCustomArguments` and is therefore mediated by `validateCustomArguments()` before `ProcessBuilder.start()`.

The fixed path explicitly covers:
- `DoclingProducer.addCustomArguments(...)`, which reads `CamelDoclingCustomArguments`.
- `DoclingProducer.validateCustomArguments(...)`, which rejects null arguments, shell metacharacters, producer-managed flags, unknown long/short flags, and path traversal in custom-argument values.
- `DoclingProducer.validateLongFlag(...)` / `validateShortFlag(...)`, which implement the allowlist behavior.
- `DoclingProducer.validatePathSafety(...)`, which rejects literal `../` / `..\` and normalized path components named `..` for arguments that pass through the custom-argument validator.

The fix does not cover the separate output-path header path:
- `DoclingProducer.addOutputDirectoryArguments(...)` reads `CamelDoclingOutputFilePath` and appends `--output` plus the header value directly to the command list.
- In 4.18.3 and 4.21.0 bytecode, no call to `validatePathSafety(...)` occurs in `addOutputDirectoryArguments(...)` before the value is supplied to `ProcessBuilder`.

The Apache Camel security documentation confirms that the Camel PMC treats trust boundaries and route/operator responsibility as part of security triage, but it also lists CVE-2026-40047 as an accepted `Camel-Docling` issue for argument injection and path traversal in `DoclingProducer`. This variant uses the same accepted trust model as the parent: a route maps externally influenced HTTP data into a Camel docling control header.

## Variant / Alternate Trigger
The bypass path is a path-bearing header rather than the parent custom-argument header.

Exact runtime entry point tested:
- HTTP endpoint: `GET /convert`
- Attacker-controlled input: HTTP header `X-Out: ../escaped-output`
- Route behavior: the harness joins a configured safe base directory with `X-Out` and sets `CamelDoclingOutputFilePath` to `<safe-output>/../escaped-output`.
- Sink: `DoclingProducer.addOutputDirectoryArguments(...)` appends `--output <safe-output>/../escaped-output` to the list passed to `new ProcessBuilder(command).start()`.

Relevant code path:
- `org.apache.camel.component.docling.DoclingProducer.buildDoclingCommand(...)`
- `org.apache.camel.component.docling.DoclingProducer.addCustomArguments(...)` / `validateCustomArguments(...)` for the fixed parent path
- `org.apache.camel.component.docling.DoclingProducer.addOutputDirectoryArguments(...)` for the bypass path
- Evidence bytecode dumps: `bundle/logs/vuln_variant/javap_docling_4.18.3.txt` and `bundle/logs/vuln_variant/javap_docling_4.21.0.txt`

The script also sends a control request with `args=--pruva-unknown-flag` on fixed lines. That control is rejected with the expected allowlist error, proving that the fixed custom-argument validator is active while the output-header path remains reachable.

## Impact
- **Package/component affected:** Maven package `org.apache.camel:camel-docling`, specifically `DoclingProducer` handling of `CamelDoclingOutputFilePath`.
- **Affected versions tested:**
  - Affected control: Apache Camel / `camel-docling` 4.18.2
  - Fixed bypass target: Apache Camel / `camel-docling` 4.18.3
  - Latest-tested bypass target: Apache Camel / `camel-docling` 4.21.0
- **Risk level and consequences:** The reproduced impact is path traversal in the `docling --output` value after crossing an HTTP-to-Camel route boundary. In the proof harness, a docling executable writes a marker outside the intended `SAFE_OUTPUT_DIR`. In a real deployment, the consequence depends on the installed `docling` CLI behavior and filesystem permissions, but it can redirect generated output to unintended directories.

## Impact Parity
- **Disclosed/claimed maximum impact for parent:** argument injection / path traversal, with the repro-stage proof also demonstrating a plugin-mediated code-execution boundary effect for custom arguments.
- **Reproduced impact from this variant run:** path traversal through `CamelDoclingOutputFilePath` on fixed 4.18.3 and latest-tested 4.21.0.
- **Parity:** `partial`. The variant reproduces the path-traversal portion of the parent root cause on fixed releases, but it does not reproduce plugin-mediated code execution.
- **Not demonstrated:** arbitrary code execution, shell metacharacter command injection, or arbitrary file overwrite beyond the controlled marker written by the proof docling executable.

## Root Cause
The same underlying defect is incomplete validation at the boundary between Camel exchange headers and the external `docling` CLI argv. The fix added strong validation for `CamelDoclingCustomArguments`, but validation was not applied uniformly to all attacker-influenceable argv contributors.

In fixed 4.18.3, `validateCustomArguments(...)` calls `validatePathSafety(...)` for non-flag custom values and for long-flag values after `=`, while `addOutputDirectoryArguments(...)` directly appends the `CamelDoclingOutputFilePath` header value:

```text
--output <CamelDoclingOutputFilePath>
```

The fixed/latest bytecode evidence shows `addOutputDirectoryArguments(...)` reading `CamelDoclingOutputFilePath` and adding the value to the command list without normalization or traversal rejection. The tested Apache Camel tag identities were resolved as:
- `camel-4.18.2`: `3864c200f46aa055a0714a069c702c433aca7097`
- `camel-4.18.3`: `6cc2920f7fd0dc642162aca00288f8dc0c9e37de`
- `camel-4.21.0`: `a84c468557bba6d400fb9675351d7efe64ce01b4`

The exact source fix commit was not identified separately from release tags during this run.

## Reproduction Steps
1. Run `bundle/vuln_variant/reproduction_steps.sh` from any directory.
2. The script builds a small Camel/Jetty harness under `bundle/vuln_variant/harness_output_header`, creates a safe output directory, and installs a deterministic proof `docling` executable under `bundle/vuln_variant/bin`.
3. It tests three versions side by side:
   - `4.18.2` vulnerable control
   - `4.18.3` fixed target
   - `4.21.0` latest-tested target
4. For each version, it sends:
   - A custom-argument control request (`args=--pruva-unknown-flag`) to show the fixed allowlist behavior on 4.18.3+.
   - The variant request (`GET /convert` with `X-Out: ../escaped-output`) to map the traversal value into `CamelDoclingOutputFilePath`.
5. Expected bypass evidence: on 4.18.3 and 4.21.0, the docling invocation log contains `--output <safe-output>/../escaped-output`, and a marker is written in `<attempt>/escaped-output`, outside `<attempt>/safe-output`.

## Evidence
Key artifacts:
- `bundle/logs/vuln_variant/reproduction_steps.log`
- `bundle/logs/vuln_variant/fixed_4.18.3_docling_invocations.log`
- `bundle/logs/vuln_variant/fixed_4.18.3_escaped_marker.txt`
- `bundle/logs/vuln_variant/fixed_4.18.3_custom_args_control_response.txt`
- `bundle/logs/vuln_variant/latest_4.21.0_docling_invocations.log`
- `bundle/logs/vuln_variant/latest_4.21.0_escaped_marker.txt`
- `bundle/vuln_variant/runtime_manifest.json`

Representative successful bypass excerpt from `reproduction_steps.log`:

```text
[attempt] fixed_4.18.3 http=500 invoked=true escaped_marker=true control_http=500 control_rejected=true
[attempt] latest_4.21.0 http=500 invoked=true escaped_marker=true control_http=500 control_rejected=true
[result] BYPASS REPRODUCED: CamelDoclingOutputFilePath traversal reaches docling on fixed/latest version(s).
```

Representative fixed-version argv evidence:

```text
ARGV[3]=--output
ARGV[4]=.../attempt_fixed_4.18.3/safe-output/../escaped-output
NORMALIZED_OUTPUT=.../attempt_fixed_4.18.3/escaped-output
```

Representative marker evidence:

```text
PRUVA_OUTPUT_HEADER_TRAVERSAL_REACHED
raw_output=.../safe-output/../escaped-output
normalized_output=.../escaped-output
```

Representative fixed custom-argument control evidence:

```text
java.lang.IllegalArgumentException: Custom argument '--pruva-unknown-flag' is not a recognized docling CLI flag. Only known docling flags are permitted as custom arguments.
```

Environment details captured include Java version, Maven version, tested Camel release identities, service logs, per-version docling argv logs, and marker files.

## Recommendations / Next Steps
- Apply the same path-normalization and traversal rejection used for custom argument values to `CamelDoclingOutputFilePath` before adding it to the command list.
- Validate every path-bearing docling exchange header at the point where it is converted into CLI argv, not only values supplied through `CamelDoclingCustomArguments`.
- Consider resolving output paths against an explicitly configured safe base directory and rejecting any normalized path that escapes that base.
- Add regression tests for:
  - `CamelDoclingOutputFilePath` containing `../`, `..//`, and normalized traversal.
  - Fixed custom-argument rejection and output-header rejection in the same test case.
  - Any other docling path-bearing headers that are appended to `ProcessBuilder` arguments.

## Additional Notes
- The reproduction script was run twice consecutively after final edits; both runs completed and reproduced the bypass with exit code `0`.
- HTTP status is `500` in the output-header attempts because the Camel/docling harness later fails while processing the proof output format. This does not affect the bypass proof: the docling executable was started by `ProcessBuilder`, received the unsafe `--output` value, normalized it outside the safe directory, and wrote the marker.
- The proof docling executable is a deterministic local stand-in for the external CLI. It does not invoke a shell and only writes a marker under the run bundle.