本项目演示了 Apache Camel 的 camel-pqc 组件中的一个 Java 反序列化漏洞,编号为 CVE-2026-43867。AwsSecretsManagerKeyLifecycleManager.deserializeMetadata() 从 AWS Secrets Manager 的密钥中读取持久化的后量子密钥元数据,其流程是对存储的值进行 Base64 解码,然后使用原始的 java.io.ObjectInputStream.readObject() 进行反序列化,并且 没有设置 ObjectInputFilter —— 转换为 KeyMetadata 类型的操作发生在 readObject() 返回 之后,因此任何 readObject() 的副作用都会先于类型转换执行。能够写入该密钥的主体(拥有 secretsmanager:PutSecretValue 权限)可以存储一个经过精心构造的序列化对象,该对象会在正常的密钥生命周期操作中被反序列化,从而可能导致 代码执行。
安全公告:https://camel.apache.org/security/CVE-2026-43867.html
与 CVE-2026-46590 是相同的缺陷(独立报告;该公告还涵盖了 HashiCorp Vault 和基于文件的同级管理器),并且是 CVE-2026-40048(CAMEL-23200)的 不完整修复后续 —— 当时将
FileBasedKeyLifecycleManager更改为 JSON/PKCS#8/X.509 格式,但未添加ObjectInputFilter,也未覆盖 AWS/Vault 管理器。
// AwsSecretsManagerKeyLifecycleManager - 受影响的 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)) { // 没有 ObjectInputFilter
return (KeyMetadata) ois.readObject(); // 在类型转换之前,gadget 在此触发
}
}
getKeyMetadata(keyId) 读取名为 <keyPrefix>/<keyId>/metadata 的密钥,解析其 JSON 封装({"metadata":"<base64>","keyId":...,"algorithm":...}),并将 metadata 字段传递给 deserializeMetadata。修复版本(4.18.3 / 4.21.0)引入了一个共享的 KeyMetadataCodec,它为所有管理器以 JSON 格式存储元数据,并通过一个允许列表的 ObjectInputFilter 约束剩余遗留的 ObjectInputStream 读取。
受害者 是使用 AWS 管理器管理 PQC 密钥的应用程序。攻击者 是能够写入元数据密钥(拥有 secretsmanager:PutSecretValue 权限)的任何主体。本 PoC 使用 LocalStack 模拟 AWS Secrets Manager;/exploit/attack 端点写入一个精心构造的元数据密钥,然后驱动管理器的读取路径。
CVE-2026-43867/
├── pom.xml # camel-pqc 4.18.2 + aws-sdk secretsmanager 2.41.28 + commons-collections 3.2.1
├── Dockerfile # 运行应用程序(为 gadget 构建添加 --add-opens)
├── docker-compose.yml # LocalStack(Secrets Manager)+ 复现工具应用
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── Gadget.java # CommonsCollections6 gadget,在 readObject() 期间触发
│ └── ExploitController.java # 写入精心构造的密钥,然后调用 getKeyMetadata()
└── resources/
└── application.properties
在实际攻击中,序列化字节是由攻击者离线生成的(例如使用 ysoserial)。本 PoC 在进程内构建 gadget,这就是为什么 JVM 以
--add-opens java.base/java.util=ALL-UNNAMED运行 —— 这是一个 gadget 构造细节,与漏洞无关。
mvn clean package -DskipTests
docker compose up -d --build
这将启动 LocalStack(模拟 AWS Secrets Manager)和复现工具应用,该应用通过端点覆盖将其 AwsSecretsManagerKeyLifecycleManager 指向 LocalStack。
curl -s http://localhost:8080/exploit/attack
# -> 已将精心构造的序列化元数据写入 AWS Secrets Manager 密钥 'pqc/keys/victim-key/metadata'。
# getKeyMetadata() 抛出 java.lang.ClassCastException (预期 — gadget 在 readObject 期间运行...)
#
# >>> RCE 证明 — /tmp/pwned 存在:true
docker exec cve-2026-43867 ls -la /tmp/pwned
docker compose down
任何使用 AwsSecretsManagerKeyLifecycleManager 的应用程序,如果其密钥元数据密钥能够被非应用程序自身可信身份的第三方写入,则可能受到影响。反序列化发生在普通的密钥生命周期操作中(getKeyMetadata、loadExistingKeys、listKeys、轮换检查等)。
AwsSecretsManagerKeyLifecycleManager。secretsmanager:PutSecretValue 权限)。commons-collections:3.2.1)。升级到 4.18.3 / 4.21.0(CAMEL-23726)。元数据以 JSON 格式存储,任何剩余遗留的 ObjectInputStream 读取都通过一个允许列表的 ObjectInputFilter 进行约束。
在升级之前:
secretsmanager:PutSecretValue 权限进行限制,仅允许应用程序自身身份使用(最小权限 IAM)。本复现工具仅供 安全研究和授权测试 使用,针对的是 已公开披露并修复 的漏洞。未经明确许可,请勿将其用于任何系统。
| 属性 | 值 |
|---|
| 组件 | camel-pqc (AwsSecretsManagerKeyLifecycleManager) |
| 受影响类 | org.apache.camel.component.pqc.lifecycle.AwsSecretsManagerKeyLifecycleManager#deserializeMetadata |
| CWE | CWE-502:不可信数据的反序列化 |
| 影响 | 密钥管理应用程序中的代码执行(需要对元数据密钥具有写入权限) |
| 受影响版本 | 从 4.18.0 到 4.18.3 之前,从 4.19.0 到 4.21.0 之前 |
| 修复版本 | 4.18.3、4.21.0(camel-pqc 不在 4.14.x LTS 线中) |
| JIRA | CAMEL-23726 |
| 报告者 | Venkatraman Kumar (Securin) |