本项目演示了 Apache Camel 的 camel-netty-http 和 camel-vertx-http 组件中的一个 Java 反序列化漏洞,编号为 CVE-2026-40859。当生产者端点配置了 transferException=true(或组件级别的 allowJavaSerializedObject=true)时,后端 HTTP 响应带有失败状态和 Content-Type: application/x-java-serialized-object,其响应体会通过原生的 java.io.ObjectInputStream 反序列化,并且 没有设置 ObjectInputFilter。能够控制 Camel 生产者所通信的后端(例如被入侵的服务,或对明文 HTTP 连接实施中间人攻击)的攻击者,可以返回精心构造的序列化对象,如果类路径上存在 gadget 链,则可以在 Camel 主机上实现远程代码执行。
安全公告:https://camel.apache.org/security/CVE-2026-40859.html
| 属性 | 值 |
|---|---|
| 组件 | camel-netty-http, camel-vertx-http(生产者端) |
| 受影响类 | org.apache.camel.component.netty.http.NettyHttpHelper#deserializeJavaObjectFromStream(以及 VertxHttpHelper#deserializeJavaObjectFromStream) |
| CWE | CWE-502:不可信数据的反序列化 |
| 影响 | 远程代码执行 (RCE) |
| 前提条件 | transferException=true(或 allowJavaSerializedObject=true)+ throwExceptionOnFailure=true(默认)+ 攻击者可控制的后端 |
| 受影响版本 | 从 4.0.0 到 4.14.8 之前,从 4.15.0 到 4.18.3 之前,从 4.19.0 到 4.20.0 之前 |
| 修复版本 | 4.14.8, 4.18.3, 4.20.0 |
| JIRA | CAMEL-23324 |
| 报告者 | Venkatraman Kumar (Securin) |
默认配置下无法利用 —
transferException默认为false。PoC 启用了该选项,模拟希望实现远程异常传播的应用。
在非 2xx 响应时,netty-http 生产者(throwExceptionOnFailure=true,默认值)通过 populateNettyHttpOperationFailedException 从响应构建异常。如果启用了 transferException 且响应携带了序列化对象的内容类型,则会对响应体进行反序列化:
// NettyHttpHelper.populateNettyHttpOperationFailedException(...) - 受影响版本
if (transferException) {
String contentType = response.headers().get(NettyHttpConstants.CONTENT_TYPE);
if (NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) { // application/x-java-serialized-object
InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, response);
if (is != null) {
Object body = deserializeJavaObjectFromStream(is); // <-- 漏洞 sink
if (body instanceof Exception) {
return (Exception) body;
}
}
}
}
// NettyHttpHelper.deserializeJavaObjectFromStream(InputStream) - 受影响版本
ObjectInputStream ois = new ObjectInputStream(is); // 无 ObjectInputFilter
answer = ois.readObject(); // gadget 在此触发
Gadget 在 readObject() 内部执行,早于 instanceof Exception 检查——因此 payload 甚至不必是一个异常对象。camel-vertx-http 在 VertxHttpHelper.deserializeJavaObjectFromStream 中存在相同的漏洞 sink。
from("direct:call")
.to("netty-http://backend-host:PORT/path?transferException=true");
// throwExceptionOnFailure 默认为 true
任何生产者调用,如果其后端返回 5xx + application/x-java-serialized-object,就会触发漏洞 sink。
受害者是 Camel 生产者(执行反序列化)。攻击者控制其所调用的后端。在这个自包含的 PoC 中,两个角色运行在同一个 JVM/容器中:嵌入式原始套接字 HTTP 服务器(MaliciousBackend)扮演攻击者控制的后端,Camel 路由(VictimRoute)是受害者。
CVE-2026-40859/
├── pom.xml # camel-netty-http 4.18.2 + commons-collections 3.2.1 (gadget)
├── Dockerfile # 运行应用(附带 --add-opens,仅用于构建 gadget 时)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # 受害者:netty-http 生产者,transferException=true
│ ├── MaliciousBackend.java # 攻击者后端:返回 500 + 序列化对象响应体,监听 :9999
│ ├── Gadget.java # CommonsCollections6 gadget,在 readObject() 期间触发
│ └── ExploitController.java # /exploit/attack 驱动生产者调用
└── resources/
└── application.properties
在实际攻击中,序列化字节由攻击者离线生成(例如使用 ysoserial);只有受害者需要类路径上存在 gadget 链。本 PoC 为了方便而在进程内构建 gadget,因此 JVM 以
--add-opens java.base/java.util=ALL-UNNAMED启动——该标志是 gadget 构建的细节,与漏洞无关。
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> producer threw ...NettyHttpOperationFailedException (预期行为)
#
# >>> RCE 证明 — /tmp/pwned 存在: true
docker exec cve-2026-40859 ls -la /tmp/pwned
docker compose down
任何配置了 transferException=true(或 allowJavaSerializedObject=true)且与攻击者可控制或拦截的后端通信的 camel-netty-http / camel-vertx-http 生产者:
http://)生产者连接上的中间人攻击,替换响应内容。transferException=true(或组件级别的 allowJavaSerializedObject=true)。throwExceptionOnFailure=true(默认值)。5xx + application/x-java-serialized-object。commons-collections:3.2.1)。升级到 4.14.8 / 4.18.3 / 4.20.0。修复措施为两个帮助类添加了默认的 ObjectInputFilter 白名单(java.**;javax.**;org.apache.camel.**;!*),可通过新的端点选项 deserializationFilter 或 JVM 全局的 -Djdk.serialFilter 系统属性进行自定义。
在升级之前:
transferException=true / allowJavaSerializedObject=true。https),以防止响应在传输过程中被替换。-Djdk.serialFilter=java.**;org.apache.camel.**;!*。此复现工具仅用于安全研究和授权测试,针对的是已公开披露并已修复的漏洞。未经明确许可,请勿将其用于任何系统。