CVE-2026-41855
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Framework is the foundational application framework for the Java platform, providing dependency injection, data access, transaction management, and integration support for messaging systems. Its spring-jms module bundles MappingJackson2MessageConverter, a JMS MessageConverter that uses Jackson to serialize outbound objects to JSON and to deserialize inbound JMS messages back into Java objects. To know which Java type an inbound message should be deserialized into, the converter reads a type identifier from a configurable JMS message header (the typeIdPropertyName property) and resolves it to a class.
A high-severity vulnerability (CVE-2026-41855) has been identified in that converter and in its Jackson 3 successor JacksonJsonMessageConverter. The type identifier read from the inbound message header is loaded as a class and used as the Jackson deserialization target without any allow-list restriction. An attacker who can place a message on a JMS destination that the application consumes can therefore set the type-id header to an arbitrary class name, causing the converter to instantiate and populate that class. In an untrusted JMS environment this enables arbitrary class instantiation and gadget-class deserialization, which can lead to unauthorized actions up to remote code execution depending on the gadget classes present on the consumer's classpath.
Per OWASP, deserialization is the process of taking data structured in some format and rebuilding it into an object, and insecure deserialization can lead to remote code execution; even where it does not result in remote code execution, it can be used to perform replay attacks, injection attacks, and privilege-escalation attacks. Here the untrusted data is the inbound JMS message: the type-id header chooses the class that Jackson instantiates, so an attacker who controls messages on a consumed destination controls the deserialization target.
The CVSS v3.1 vector for this vulnerability is AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (High). The attack vector is Network and no privileges or user interaction are required, because the attacker only needs to publish a crafted message to a JMS destination the application consumes. Attack complexity is High because successful exploitation depends on a usable gadget class being present on the consumer's classpath. The impact is High across confidentiality, integrity, and availability, reflecting that gadget-class deserialization can result in full compromise of the consuming application.
This issue affects Spring Framework >=4.3.0 <=4.3.30, >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, and >=7.0.0 <=7.0.7.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-jms
- Affected versions: >=4.3.0 <=4.3.30, >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, >=7.0.0 <=7.0.7
- GitHub repository: https://github.com/spring-projects/spring-framework
- Published packages: https://central.sonatype.com/artifact/org.springframework/spring-jms
- Package manager: Maven
- Fixed in:
- NES for Spring Framework 4.3.x, 5.3.x, 6.1.x
- Spring Framework 6.2.19, 7.0.8 (OSS)
Vulnerability Info
The vulnerability is in MappingJackson2MessageConverter in the spring-jms module, specifically in the getJavaTypeForMessage(Message) method that runs whenever the converter deserializes an inbound JMS message. The method reads a type identifier from the message header named by typeIdPropertyName, and if that identifier does not match an explicitly configured idClassMappings entry, it loads the named class directly with ClassUtils.forName(typeId, ...) and hands it to Jackson as the deserialization target.
Pre-fix, the type-id header value flows unrestricted from the inbound message into class loading and deserialization:
protected JavaType getJavaTypeForMessage(Message message) throws JMSException {
String typeId = message.getStringProperty(this.typeIdPropertyName);
if (typeId == null) {
throw new MessageConversionException(
"Could not find type id property [" + this.typeIdPropertyName + "] on message [" +
message.getJMSMessageID() + "] from destination [" + message.getJMSDestination() + "]");
}
Class<?> mappedClass = this.idClassMappings.get(typeId);
if (mappedClass != null) {
return this.objectMapper.constructType(mappedClass);
}
try {
Class<?> typeClass = ClassUtils.forName(typeId, this.beanClassLoader);
return this.objectMapper.constructType(typeClass);
}
catch (Throwable ex) {
throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex);
}
}
typeId is taken verbatim from message.getStringProperty(this.typeIdPropertyName), an attacker-controllable JMS message header. When it does not match a configured mapping it is passed straight to ClassUtils.forName(typeId, this.beanClassLoader) and then to objectMapper.constructType(...), so the sender of the message chooses which class Jackson instantiates and populates. If a viable gadget class is on the consumer's classpath, this becomes a deserialization gadget chain and can escalate to remote code execution. Because the converter is a standard component wired into JMS listeners, any application that consumes JSON-over-JMS messages from a destination an attacker can write to is exposed.
Mitigation
Only recent versions of Spring Framework receive community support and updates. Older versions, including the 4.3.x, 5.3.x, and 6.1.x lines, have no publicly available open-source fix for this vulnerability.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported open-source version of Spring Framework that contains the fix. The OSS fix ships in Spring Framework 6.2.19 (6.2.x line) and 7.0.8 (7.0.x line).
- After upgrading, in any untrusted JMS environment call setTrustedPackages(...) on the Jackson JMS converter to restrict deserialization to the packages the application legitimately exchanges. The fix is opt-in hardening and does not restrict deserialization until trusted packages are configured.
- As an interim hardening step on a vulnerable deployment, ensure the JMS destinations the application consumes cannot be written to by untrusted producers, and prefer explicit setTypeIdMappings(...) allow-listing of the exact classes exchanged rather than open class resolution from the type-id header.
- Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Spring Framework.
Credits
- wo1enca1ca1 (finder)