CVE-2026-21452MessagePack for Java是一个用于Java语言的序列化实现库,广泛应用于分布式系统、微服务架构、模型文件序列化以及跨语言数据交换等场景。该库在处理.msgpack格式文件时存在一个严重的拒绝服务漏洞。漏洞源于EXT32对象(扩展类型数据)的反序列化过程中,库在解析扩展头时采用了延迟加载策略,但随后在实例化扩展数据时盲目信任了EXT头部中声明的有效载荷长度字段。当应用程序调用ExtensionValue.getData()方法时,库会尝试根据声明的长度分配相应大小的字节数组,但未对该长度施加任何上限约束。攻击者可以构造一个仅包含几百字节的畸形但语法有效的.msgpack文件,其中EXT32对象声明了一个超大甚至超出JVM堆内存大小的有效载荷长度。这会触发无限制的堆内存分配请求,导致JVM堆内存耗尽、频繁的垃圾回收操作、进程终止或抛出OutOfMemoryError。由于攻击文件体积小且格式合法,可以轻易绕过基于文件大小或基本格式校验的安全扫描工具。该漏洞影响所有使用MessagePack for Java反序列化不可信.msgpack文件的应用程序,包括模型注册中心、推理服务、CI/CD流水线以及云端模型托管平台等生产环境,可能造成服务完全不可用并引发级联故障。
MessagePack是一种高效的二进制序列化格式,支持多种数据类型,其中包括EXT(扩展类型)用于存储自定义二进制数据。EXT32是扩展类型的一种变体,其头部结构包含:固定标记字节(0xC7)、类型字段以及一个4字节的长度字段。在MessagePack-Java < 0.9.11的实现中,ExtCodec在解码EXT32时,首先读取4字节长度字段得到extLength,然后创建ExtensionHeader对象存储该长度值。关键问题在于:ExtensionHeader的解析是惰性的(lazy),但后续在ExtensionValue.getData()方法中,代码直接使用header中存储的extLength调用ByteBuffer.allocate(extLength)进行堆内存分配,完全没有验证该长度是否在合理范围内。攻击者可以利用这一特性,在合法的EXT32头部中声明一个极大的extLength值(如Integer.MAX_VALUE或更大的正整数),当受害者反序列化该文件时,JVM会尝试分配一个超出可用内存的连续字节数组。由于Java的byte[]数组索引使用int类型,最大可分配约2GB的连续内存,在大多数服务器配置下这已远超可用堆空间。攻击者只需构造一个包含单个EXT32对象的消息,文件大小可能不超过20字节,但能触发数GB的内存分配请求。