oscerd/CVE-2026-49042
GitHub: oscerd/CVE-2026-49042
该项目复现了 Apache Camel langchain4j-tools 组件因工具调用参数未经验证直接写入 Exchange header 而导致 prompt injection 到 RCE 的漏洞链。
Stars: 0 | Forks: 0
# camel-langchain4j-tools Prompt-Injection → Header-Injection 复现代码库 (CVE-2026-49042)
本项目演示了 Apache Camel 的 `camel-langchain4j-tools` 组件中的一个**输入验证缺陷**
(该系列也包括 `camel-langchain4j-agent` 和 `camel-spring-ai-tools`),被追踪为 **CVE-2026-49042**。
当 Camel 路由作为 LLM agent 时,tools producer 会询问模型调用哪个工具以及使用哪些
参数。模型会回复一个包含参数的 JSON 对象。受影响的 producer 随后会将**该 JSON 中的每个字段直接复制到 Exchange 消息头中** —— 且**没有针对工具声明的参数 schema 进行任何过滤**:
```
// LangChain4jToolsProducer.invokeTools (affected 4.18.2)
JsonNode jsonNode = objectMapper.readValue(toolExecutionRequest.arguments(), JsonNode.class);
jsonNode.fieldNames().forEachRemaining(name -> {
// ...type-convert value...
exchange.getMessage().setHeader(name, headerValue); // EVERY field -> a header, no schema check
});
camelToolSpecification.getConsumer().getProcessor().process(exchange); // then the tool route runs
```
LLM 的输出是**不受信任的** —— 它通常会被 **prompt injection** 操纵,最危险的是来自 agent 摄取内容(文档、网页、电子邮件、数据库行)的*间接* prompt injection。以这种方式被操纵的模型可以发出**超出工具声明参数的额外参数字段**。由于这些字段名称会原封不动地成为 Exchange header,攻击者可以设置 Camel 的**控制 header** —— 如 `CamelExecCommandExecutable`、
`CamelHttpUri`、`CamelFileName` 等 —— 从而操纵工具路由使用的任何下游组件。
此 PoC 将其影响演示为**远程代码执行 (CWE-20 → 命令执行)**:一个无害的
“获取系统状态”工具通过 `exec:` 组件运行主机诊断;被 prompt injection 的模型注入了
`CamelExecCommandExecutable=/bin/sh` 和 `CamelExecCommandArgs=-c "id > /tmp/pwned"`,该诊断随后
被攻击者选择的命令所替换。当工具路由改用 HTTP 或 file producer 时,**同样的原语**也会产生 SSRF(通过 `CamelHttpUri`)或任意文件写入(通过 `CamelFileName`)。
安全通告:https://camel.apache.org/security/CVE-2026-49042.html
## 漏洞概述
| 属性 | 值 |
|----------|-------|
| **Component** | `camel-langchain4j-tools` (也包括 `camel-langchain4j-agent`、`camel-spring-ai-tools`) |
| **Affected Class** | `org.apache.camel.component.langchain4j.tools.LangChain4jToolsProducer#invokeTools` |
| **CWE** | CWE-20 (不当的输入验证) — 未经筛选的工具调用参数成为了 Exchange 控制 header |
| **Impact** | RCE / SSRF / 任意文件写入,取决于工具路由的下游 producer |
| **Preconditions** | 一个 Camel LLM-agent 路由,其工具操作到达可由 header 操纵的组件 (exec/http/file/…);模型可通过(间接)prompt injection 被操纵 |
| **Affected Versions** | 4.8.0–4.14.7, 4.15.0–4.18.2, 4.19.0–4.20.x |
| **Fixed Versions** | 4.14.8, 4.18.3, 4.21.0 |
| **JIRA** | CAMEL-23621 (PR [apache/camel#23535](https://github.com/apache/camel/pull/23535)) |
| **Credit** | Yu Bao (PayPal) |
## 为什么不需要真实的 LLM
该漏洞与使用哪种模型以及任何特定的越狱无关。它只要求模型
能够被操纵以添加额外的工具调用参数字段 —— 而 prompt injection 能够可靠地做到这一点。因此,此
复现代码库提供了一个 `MockChatModel`,它扮演被 prompt injection 的模型的角色:在第一轮中,它
返回一个 `get_system_status` 工具调用,其参数携带了两个额外的 `CamelExec*` 字段;在附加工具
结果后,它返回一个普通的最终答案。这正是被越狱或被间接注入的真实
模型会发出的 JSON —— Camel 中的漏洞代码路径是完全相同的。
## 受害者路由
```
// A benign tool: declared parameter is only "host"; action runs a host diagnostic via exec.
from("langchain4j-tools:sysTool?tags=demo&name=get_system_status"
+ "&description=Return the operational status of a host¶meter.host=string")
.to("exec:echo?args=diagnostic-ok") // hijacked when CamelExecCommand* headers are present
.setBody(constant("status: OK"));
// The agent endpoint: user message -> LLM -> tool calls.
from("platform-http:/chat")
.process(e -> e.getMessage().setBody(List.of(UserMessage.from(e.getMessage().getBody(String.class)))))
.to("langchain4j-tools:agent?tags=demo&chatModel=#mockModel")
.convertBodyTo(String.class);
```
作者原本只期望攻击者能影响 `host`(一个工具参数)。他们从未授予模型
设置任意 Exchange header 的能力 —— 但受影响的 producer 恰恰做了这件事。
## 仓库布局
一切都在一个自包含的容器中运行:agent、工具路由、模拟被 prompt injection 的 LLM 以及
攻击者驱动程序。
```
CVE-2026-49042/
├── pom.xml # camel-platform-http + camel-langchain4j-tools + camel-exec 4.18.2; langchain4j 1.11.0
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── MockChatModel.java # fake prompt-injected LLM: emits the malicious tool-call arguments
│ ├── ModelConfig.java # registers the mock as the agent's ChatModel bean
│ ├── VictimRoutes.java # tool route (-> exec) + agent route (platform-http:/chat)
│ └── ExploitController.java # attacker: POST /chat with a prompt injection, then check /tmp/pwned
└── resources/
└── application.properties
```
## 前置条件
- Docker 和 Docker Compose
- Java 17+ 和 Maven 3.8+
## 复现步骤
```
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
```
### 预期输出
```
=== CVE-2026-49042 — camel-langchain4j-tools prompt-injection -> header-injection ===
1) Attacker sends an agent request carrying a prompt injection to POST /chat
(declared tool parameter is only 'host'; everything else is smuggled).
2) Agent replied: The system status for prod-db-1 is: OK.
HTTP status: 200
3) Downstream exec: hijack result
/tmp/pwned was created by the injected command. Its content is the
output of `id`, run by the container's process:
uid=0(root) gid=0(root) groups=0(root)
>>> PROVEN: a prompt-injected tool-call argument became a Camel control header and
>>> executed an attacker-chosen command. Remote code execution: true
```
## 攻击向量
任何 Camel LLM-agent 路由(`langchain4j-tools`、`langchain4j-agent`、`spring-ai-tools`),只要其工具操作到达了
可由 Camel header 操纵的组件。注入的字段名称可以是任何 Camel 控制 header,例如:
- `CamelExecCommandExecutable` / `CamelExecCommandArgs` → **RCE**(此 PoC)
- `CamelHttpUri` → **SSRF**(以 HTTP producer 结尾的工具路由)
- `CamelFileName` → **任意文件写入 / 路径遍历**(以 file producer 结尾的工具路由)
触发原因是到达模型的不受信任的内容 —— 最现实的情况是来自
agent 处理的数据的**间接 prompt injection**,而不一定是恶意的最终用户。
## 建议修复方案
升级到 **4.14.8 / 4.18.3 / 4.21.0** (CAMEL-23621)。修复后,只有**声明的参数**会被
提升为 header,因此模型无法再引入任意的 Camel 控制 header。
## 缓解措施
在升级之前:
- 让 agent 工具路由远离可由 header 操纵的接收器 (`exec`、`http`、`file`、…),或者硬性固定这些
组件中与安全相关的值,以使 header 无法覆盖它们。
- 在工具路由中的 tools producer 和
下游组件之间插入一个 `removeHeaders("Camel*")`(以及任何其他控制 header 清理操作)。
- 将所有 LLM 输出视为不受信任的,并对 agent 摄取的任何内容应用 prompt injection 防御。
## 免责声明
此复现代码库仅用于**安全研究和授权测试**,针对的是**已公开披露并已修复的**
漏洞。未经明确许可,请勿将其用于系统。注入的命令是一个无害的
`id`,仅写入一个标记文件。
标签:JS文件枚举, 域名枚举, 请求拦截