针对 Apache Camel 漏洞的可运行概念验证复现程序,该漏洞中 jgroups consumer 在无任何过滤的情况下对集群消息进行 Java 反序列化。JGroupsEndpoint.createExchange(Message) —— 对 consumer 收到的每条消息都会调用 —— 从 org.jgroups.Message.getObject() 设置 exchange body。对于 ObjectMessage(Camel jgroups producer 发送的类型),JGroups 在消息到达时通过 ObjectInputStream 对载荷进行 Java 反序列化,getObject() 返回其结果。未应用任何 java.io.ObjectInputFilter,因此从集群收到的、位于应用 classpath 上的任何可序列化类都会被实例化并执行其反序列化回调 —— 当存在可用的 gadget chain 时即可实现远程代码执行。使用默认的 new JChannel() 栈(UDP 组播、无 AUTH、无加密)时,任何能访问该集群的主机都可以在无凭据的情况下发送此类消息(CWE-502)。
仅限 Spring Boot。 本复现程序仅包含一个 Camel Spring Boot 模块。
camel-jgroups没有camel-quarkus-jgroups扩展,因此没有可复现的 Quarkus 对应版本。Spring Boot 模块演示了受影响的 以及 修复后的行为。
| 运行时 | 目录 | 技术栈 |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-jgroups 4.22.0(受影响;修复版本 4.22.1) |
一个无害的攻击者对象 —— com.example.Marker,一个普通的应用类,不在修复版本默认允许列表(java.**、javax.**、org.apache.camel.**)中 —— 被序列化为 JGroups 线上格式,并送入真实的 JGroupsEndpoint.createExchange(...),后者通过 Message.getObject() 读取它(与 consumer 对每条收到的消息所做的调用相同)。无需 channel 或组播,因此该检查是确定性的。Marker.readObject 翻转一个标志以表明反序列化回调已执行 —— 真实的 gadget chain 会在该确切位置执行有害代码;本复现程序不包含任何 gadget。
com.example.Marker,createExchange 抛出
JGroupsException;该对象永远不会到达路由。诚实的注意事项(如公告所述): 4.22.1 / 4.18.5 的类检查在 JGroups 已反序列化载荷之后运行, 因此
readObject回调在修复版本上仍会执行 —— 这属于纵深防御。要阻止在反序列化期间运行的代码, 还必须设置 JVM 级别的-Djdk.serialFilter,并通过AUTH+ 加密保护 channel;4.23.0 还额外拒绝启动 consumer,除非已配置上述控制措施之一。本复现程序展示了类检查的差异;回调已执行标志使该注意事项可见。
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: Marker deserialized + routed; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-88900-jgroups-deserialization-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: JGroupsException rejects com.example.Marker; >>> Not exploited
| 属性 | 值 |
|---|---|
| 组件 | camel-jgroups(JGroupsEndpoint.createExchange) |
| CWE | CWE-502(不可信数据反序列化) |
| 严重程度 | 高 |
| 攻击向量 | 能够访问集群组播组/绑定端口的主机发送特制的 ObjectMessage;消费者在没有任何过滤器的情况下对其进行反序列化 |
| 影响 | 当类路径上存在 gadget 链时,可在 Camel 进程中实现远程代码执行;否则可任意实例化类 |
| 受影响版本 | 从 4.0.0 起至 4.18.5 之前,从 4.19.0 起至 4.22.1 之前 |
| 修复版本 | 4.18.5、4.22.1、4.23.0 |
| JIRA | CAMEL-24676、CAMEL-25223 |
| 报告者 | h1ei1 |
安全公告:https://camel.apache.org/security/CVE-2026-88900.html
JGroupsEndpoint 现在会在交换被路由之前,通过新增的 deserializationFilter 选项(jdk.serialFilter 语法)检查 Message.getObject() 返回的 body 的类。当该选项未设置时,如果存在 JVM 级别的 jdk.serialFilter,则遵循该设置;否则使用一份保守的默认允许列表,允许 java.**/javax.**/org.apache.camel.**,拒绝 java.net.**,并拒绝其他所有内容;被拒绝的消息会报告给消费者的 ExceptionHandler,且不会被路由。在 4.23.0(CAMEL-25223)中,除非配置了在反序列化之前生效的控制措施(JVM 级别的过滤器、jgroups.deserialization.filter 系统属性,或 AUTH+加密通道),否则消费者还会拒绝启动。acceptAllObjects=true 可恢复旧行为,但会被标记为不安全设置。
在运行消费者的 JVM 上设置 -Djdk.serialFilter(仅允许你的路由通过集群交换的类),通过 channelProperties 选项使用 AUTH 和 SYM_ENCRYPT/ASYM_ENCRYPT 保护通道,并且不要将集群的组播组或绑定端口暴露给不可信网络。
本仓库出于教育和防御目的发布:帮助 Apache Camel 用户理解该漏洞、验证自身是否受影响,并确认升级可以解决该问题。被反序列化的对象是本仓库中定义的一个无害标记类;它不包含 gadget 链,也不会执行任何有害操作。请勿将本材料用于你并不拥有或运营的系统。