{
  "variant_id": "pruva-ghsa-rpv3-6645-2vqc-output-header-path-traversal-bypass",
  "created_at": "2026-07-07T00:00:00Z",
  "variant_summary": "Bypass of the camel-docling 4.18.3 custom-argument fix: CamelDoclingOutputFilePath is a separate path-bearing header that is appended as docling --output without path-normalization/traversal validation, allowing HTTP-controlled output traversal on fixed 4.18.3 and latest-tested 4.21.0.",
  "relation": "newer_version_sibling",
  "origin_kind": "pruva_variant",
  "repository": "https://github.com/apache/camel",
  "submitted_target": {
    "target_kind": "release_range",
    "version": "4.15.0 through 4.18.2",
    "ref": "GHSA-rpv3-6645-2vqc / CVE-2026-40047",
    "display": "Apache Camel camel-docling affected range before fixed 4.18.3"
  },
  "variant_target": {
    "target_kind": "release_tag",
    "commit_sha": "6cc2920f7fd0dc642162aca00288f8dc0c9e37de",
    "version": "4.18.3",
    "ref": "refs/tags/camel-4.18.3",
    "display": "Apache Camel camel-docling 4.18.3 fixed release; bypass also reproduced on 4.21.0 tag a84c468557bba6d400fb9675351d7efe64ce01b4"
  },
  "same_root_cause_confidence": "high",
  "same_surface_confidence": "medium",
  "claimed_surface": "api_remote",
  "validated_surface": "api_remote",
  "required_entrypoint_kind": "endpoint",
  "required_entrypoint_detail": "HTTP GET /convert route maps X-Out header into CamelDoclingOutputFilePath, then invokes docling:convert",
  "attacker_controlled_input": "HTTP header X-Out: ../escaped-output; route joins it with SAFE_OUTPUT_DIR and sets CamelDoclingOutputFilePath=<safe-output>/../escaped-output",
  "trigger_path": "GET /convert with X-Out -> camel-jetty -> CamelDoclingOutputFilePath -> DoclingProducer.buildDoclingCommand() -> addOutputDirectoryArguments() -> ProcessBuilder(docling, --output, <safe-output>/../escaped-output) -> output marker written in normalized escaped-output directory",
  "observed_impact_class": "path_traversal",
  "exploitability_confidence": "medium",
  "evidence_scope": "production_camel_path_with_controlled_docling_cli_stub",
  "runtime_manifest_present": true,
  "end_to_end_target_reached": true,
  "inferred": false,
  "file_path": "components/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java",
  "line_start": 1900,
  "line_end": 1908,
  "secondary_anchors": [
    {
      "file_path": "components/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java",
      "line_start": 1761,
      "line_end": 1764
    },
    {
      "file_path": "components/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java",
      "line_start": 1769,
      "line_end": 1826
    },
    {
      "file_path": "components/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java",
      "line_start": 1860,
      "line_end": 1892
    }
  ],
  "review_scope_paths": [
    "components/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java",
    "components/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingHeaders.java",
    "components/camel-docling/src/test/java/org/apache/camel/component/docling/"
  ],
  "artifact_refs": {
    "variant_manifest": "bundle/vuln_variant/variant_manifest.json",
    "validation_verdict": "bundle/vuln_variant/validation_verdict.json",
    "runtime_manifest": "bundle/vuln_variant/runtime_manifest.json",
    "repro_log": "bundle/logs/vuln_variant/reproduction_steps.log",
    "root_cause_equivalence": "bundle/vuln_variant/root_cause_equivalence.json",
    "reproducer": [
      "bundle/vuln_variant/reproduction_steps.sh"
    ]
  }
}
