Introduction
A deserialization flaw in Spring Framework's JMS message converters lets attackers instantiate arbitrary Java classes by sending crafted messages to an untrusted JMS broker. With a suitable gadget chain, that can lead to remote code execution. Spring Framework holds over 22% of the web framework market and underpins enterprise Java applications across regulated industries, so CVE-2026-41855 reaches an unusually broad install base: all four supported release lines, from version 5.3.0 through 7.0.7.
External security researcher wo1enca1ca1 reported the vulnerability, and it was disclosed on June 8, 2026. It carries a CVSS score of 8.1 (HIGH) with full confidentiality, integrity, and availability impact. The vulnerability class is well understood (CWE-502: Deserialization of Untrusted Data). Here it meets a widely deployed framework and a patching model that restricts fixes for older release lines to commercial support customers.
Technical Information
Root Cause
CVE-2026-41855 resides in two Spring JMS message converter classes:
org.springframework.jms.support.converter.MappingJackson2MessageConverterorg.springframework.jms.support.converter.JacksonJsonMessageConverter
These converters use Jackson's polymorphic deserialization to convert JMS message payloads into Java objects. The converter blindly resolved the Java type named in an incoming JMS message header, the typeId property, via ClassUtils.forName(), with no restriction on which classes could be instantiated. The type identifier went through no allowlist, no blocklist, and no other validation before class loading.
This is a textbook instance of CWE-502 (Deserialization of Untrusted Data), which MITRE defines as a weakness where "the product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid." The CWE documentation also describes how attackers use "gadget chains," defined as "a sequence of method invocations that self-execute during the deserialization of a crafted payload." These chains repurpose legitimate classes already on the application's classpath, so the attacker does not need to inject any custom malicious code.
CVSS Vector Breakdown
The CVSS v3.1 vector AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H tells us:
| CVSS Component | Value | Interpretation |
|---|---|---|
| Attack Vector | Network | Exploitable remotely over the network |
| Attack Complexity | High | Specific conditions required (untrusted JMS environment, suitable gadget classes on classpath) |
| Privileges Required | None | No authentication needed to exploit |
| User Interaction | None | No user action required |
| Scope | Unchanged | Impact confined to the vulnerable component |
| Confidentiality Impact | High | Total information disclosure possible |
| Integrity Impact | High | Total system integrity compromise possible |
| Availability Impact | High | Total system availability loss possible |
The "High" attack complexity is what keeps this at 8.1 rather than a critical 9.x score. Exploitation requires two conditions. The JMS environment must be untrusted, meaning the attacker must be able to publish messages to the JMS broker. Suitable gadget classes must also exist on the target application's classpath. In a fully trusted environment where only authorized applications can publish messages, the attack vector is not viable. However, enterprise JMS deployments frequently involve shared brokers, cross-organizational messaging, or environments where the definition of "trusted" is ambiguous.
Attack Flow
A typical exploitation sequence proceeds as follows:
-
Reconnaissance: The attacker identifies a Spring application using
MappingJackson2MessageConverterorJacksonJsonMessageConverterthat is connected to a JMS broker they can publish to, or that accepts messages from untrusted sources. -
Payload Construction: The attacker crafts a JMS message with a
_typeheader (or equivalent type identifier property) pointing to a known gadget class on the target application's classpath. Enterprise Spring deployments typically have rich classpaths with many libraries, which significantly expands the set of available gadget classes. -
Message Delivery: The attacker publishes the crafted message to the JMS broker, on a queue or topic that the vulnerable application consumes.
-
Deserialization Trigger: When the application consumes the message, the converter reads the
typeIdfrom the message header, callsClassUtils.forName()with the attacker-specified class name, and instantiates the class during Jackson deserialization. -
Gadget Chain Execution: During deserialization, the gadget chain runs a sequence of method calls that carries out the attacker's objective. As the CWE-502 documentation notes, attackers can use gadget chains to achieve goals "such as generating a shell."
This follows the same pattern as earlier Jackson deserialization vulnerabilities such as CVE-2020-24616, an RCE vulnerability in Jackson-databind that exploited a gadget chain in the commons-dbcp2 library.
Patch Information
The Spring team published the fix on June 8, 2026, in commit 9bec52b1 (closing issue gh-36791), authored by Sébastien Deleuze and committed by Brian Clozel. The fix shipped on these release branches:
| Affected Branch | Fix Version | Availability |
|---|---|---|
| 7.0.x | 7.0.8 | OSS |
| 7.0.x | 7.0.7.1 | Commercial |
| 6.2.x | 6.2.19 | OSS |
| 6.2.x | 6.2.18.1 | Commercial |
| 6.1.x | 6.1.28 | Commercial only |
| 5.3.x | 5.3.49 | Commercial only |
The patch adds a package-level allowlist (119 lines added, 0 deleted across source and test files).
New trustedPackages Field and Setter
The converter gets a new nullable String[] field and a public setter:
private String @Nullable [] trustedPackages; public void setTrustedPackages(String... trustedPackages) { this.trustedPackages = trustedPackages.clone(); }
The defensive .clone() call prevents callers from modifying the internal array after setting it.
Private Validation Method
A new isTrustedPackage() method extracts the package name from the requested type string and checks it against the allowlist. It also handles array type descriptors correctly (e.g., [Lcom.example.MyClass; for 1D arrays, [[Lcom.example.MyClass; for 2D arrays) by stripping the array prefix:
private boolean isTrustedPackage(String requestedType) { if (this.trustedPackages != null) { String packageName = ClassUtils.getPackageName(requestedType); int lastBracketIndex = packageName.lastIndexOf('['); if (lastBracketIndex != -1 && packageName.length() > lastBracketIndex + 1 && packageName.charAt(lastBracketIndex + 1) == 'L') { packageName = packageName.substring(lastBracketIndex + 2); } for (String trustedPackage : this.trustedPackages) { if (packageName.equals(trustedPackage)) { return true; } } return false; } return true; }
When trustedPackages is null (the default, meaning setTrustedPackages was never called), the method returns true, so behavior in trusted JMS environments stays fully backward compatible. Enforcement starts only when the developer explicitly configures the allowlist.
Enforcement Gate
The security check sits in the getJavaTypeForMessage() method, right before the existing ClassUtils.forName() call that resolves the attacker-controlled typeId:
if (!isTrustedPackage(typeId)) { throw new MessageConversionException("The class '" + typeId + "' is not in the trusted packages: " + Arrays.toString(this.trustedPackages)); }
If the class's package is not on the allowlist, the converter throws a MessageConversionException before any class loading or instantiation happens, so the gadget chain never runs.
Test Coverage
The commit adds 82 lines of test code in MappingJackson2MessageConverterTests.java, covering five scenarios:
- Untrusted package rejection
- Trusted package acceptance
- Empty allowlist (rejects all)
- 1D array type handling
- 2D array type handling
Required Configuration After Upgrading
For applications in untrusted JMS environments, upgrading alone is not enough. The Spring advisory states that developers must also call setTrustedPackages(...) with the specific packages they expect. A representative configuration:
@Bean public MappingJackson2MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_type"); converter.setTrustedPackages("com.yourcompany.yourapp.domain"); return converter; }
This is an opt-in hardening pattern, similar to Spring's existing DefaultJmsListenerContainerFactory and ActiveMQ's own trusted-packages approach. The advisory describes it as "a single, secure configuration step," compared with the earlier, error-prone approach of configuring the underlying ObjectMapper directly.
Commercial Support Considerations
Organizations on Spring Framework 6.1.x or 5.3.x without commercial Tanzu Spring support cannot get patched versions through open-source channels. For those unable to buy commercial support, alternative mitigations include:
- Strict access controls on the JMS broker
- Network segmentation to isolate JMS infrastructure
- WAF or application-layer filtering
- Manual configuration of the underlying
ObjectMapperto restrict polymorphic deserialization types, which community discussions describe as "error-prone and complex"
Affected Systems and Versions
All four supported Spring Framework release lines are affected:
| Spring Framework Line | Affected Range |
|---|---|
| 7.0.x | 7.0.0 through 7.0.7 |
| 6.2.x | 6.2.0 through 6.2.18 |
| 6.1.x | 6.1.0 through 6.1.27 |
| 5.3.x | 5.3.0 through 5.3.48 |
The advisory warns that unsupported versions are also vulnerable. A vulnerable configuration requires:
- An application using
MappingJackson2MessageConverterorJacksonJsonMessageConverterfor JMS message processing - The converter configured with a
typeIdPropertyNamethat enables polymorphic type resolution - An untrusted JMS environment where unauthorized message producers can publish to the broker
- Gadget classes on the application's classpath (common in enterprise deployments with rich dependency trees)
Applications in fully trusted JMS environments, where all message producers are authorized and the broker itself is secured, are not exploitable through this vector. The advisory still recommends patching.
Vendor Security History
The Spring portfolio has had several significant security incidents before CVE-2026-41855.
The most notable was Spring4Shell (CVE-2022-22965), a remote code execution vulnerability in Spring Core that was actively exploited in the wild. Trend Micro observed exploitation that deployed the Mirai botnet, and Unit 42 documented widespread scanning and exploitation attempts. Spring4Shell showed that Spring Framework vulnerabilities draw significant attention from both opportunistic and sophisticated threat actors.
Recent Spring security advisories from 2025 and 2026 point to a growing attack surface across the portfolio:
| CVE | Project | Severity | Issue |
|---|---|---|---|
| CVE-2026-41855 | Spring Framework | High | JMS deserialization |
| CVE-2026-40983 | Micrometer | High | gRPC server DoS |
| CVE-2026-40984 | Micrometer | High | HTTP server DoS |
| CVE-2026-41715 | Reactor Netty | Medium | Credential leakage on protocol downgrade |
| CVE-2026-41863 | Spring AI | Medium | Anthropic Skills API file write |
| CVE-2026-41705 | Spring AI | High | Expression injection in MilvusVectorStore |
| CVE-2026-41712 | Spring AI | High | Cross-user data leakage via ChatMemory |
| CVE-2026-41713 | Spring AI | High | Prompt injection via memory poisoning |
| CVE-2026-40981 | Spring Cloud Config | High | GCP secrets cross-project access |
Four Spring AI advisories in May 2026 alone signal a new and growing attack surface as the portfolio expands into AI, cloud configuration, and observability tooling.
On June 8, 2026, the same day as the CVE-2026-41855 advisory, Broadcom announced expanded investment in Spring and Java ecosystem security to "prepare customers for AI-enabled threats." The announcement signals that the vendor is aware of how threats are changing. It also arrived alongside a high-severity framework vulnerability whose fixes for older release lines are commercial-only, which complicates the picture for organizations evaluating their Spring security posture.
Java deserialization vulnerabilities in general remain a persistent threat category. CVE-2026-40860, a separate JMS deserialization vulnerability where "the application deserializes the message payload without proper validation," and CVE-2026-27830, a c3p0 JNDI deserialization RCE, both show that JMS deserialization is a recurring weak point across the Java ecosystem. The MITRE EMB3D model classifies insecure deserialization as TID-326, a top-tier threat for critical infrastructure.
There is precedent for fast exploitation. According to Endor Labs, CVE-2025-24813, another Java deserialization vulnerability, was exploited about 30 hours after public disclosure. Proofpoint telemetry indicates that 12 distinct 2026 CVEs are being actively exploited in network-facing attacks. No active exploitation of CVE-2026-41855 has been confirmed as of June 9, 2026, but the window to patch before it is weaponized may be narrow.
References
- CVE-2026-41855: Spring Framework Unsafe Deserialization via JMS Converters (Spring Advisory)
- NVD Entry for CVE-2026-41855
- Spring Framework Patch Commit 9bec52b1
- Feedly CVE-2026-41855 Tracking
- CWE-502: Deserialization of Untrusted Data
- Spring Security Advisories
- CVE-2022-22965 (Spring4Shell) Analysis by Unit 42
- Spring4Shell Exploitation Analysis by Trend Micro
- Struggling to Patch Spring-Web? Try This Instead (Endor Labs)
- 2026 Vulnerability Exploitation in the Wild (Proofpoint)
- Java Deserialization Cheat Sheet
- TID-326: Insecure Deserialization (MITRE EMB3D)
- CVE-2020-24616: Jackson-databind Deserialization Vulnerability
- CVE-2026-40860: JMS Deserialization (Red Hat)
- Broadcom Expands Investment in Spring and Java Ecosystem Security
- Spring Framework Market Share (6sense)



