Automated Threat Modeling

Spring Framework CVE-2026-41855: Brief Summary of JMS Deserialization Vulnerability Affecting All Supported Release Lines

A short review of CVE-2026-41855, a high-severity deserialization flaw in Spring Framework's JMS message converters that spans versions 5.3.0 through 7.0.7. Includes patch analysis, affected version details, and mitigation guidance for untrusted JMS environments.

CVE Analysis

12 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-06-09

Spring Framework CVE-2026-41855: Brief Summary of JMS Deserialization Vulnerability Affecting All Supported Release Lines
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

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.MappingJackson2MessageConverter
  • org.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 ComponentValueInterpretation
Attack VectorNetworkExploitable remotely over the network
Attack ComplexityHighSpecific conditions required (untrusted JMS environment, suitable gadget classes on classpath)
Privileges RequiredNoneNo authentication needed to exploit
User InteractionNoneNo user action required
ScopeUnchangedImpact confined to the vulnerable component
Confidentiality ImpactHighTotal information disclosure possible
Integrity ImpactHighTotal system integrity compromise possible
Availability ImpactHighTotal 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:

  1. Reconnaissance: The attacker identifies a Spring application using MappingJackson2MessageConverter or JacksonJsonMessageConverter that is connected to a JMS broker they can publish to, or that accepts messages from untrusted sources.

  2. Payload Construction: The attacker crafts a JMS message with a _type header (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.

  3. Message Delivery: The attacker publishes the crafted message to the JMS broker, on a queue or topic that the vulnerable application consumes.

  4. Deserialization Trigger: When the application consumes the message, the converter reads the typeId from the message header, calls ClassUtils.forName() with the attacker-specified class name, and instantiates the class during Jackson deserialization.

  5. 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 BranchFix VersionAvailability
7.0.x7.0.8OSS
7.0.x7.0.7.1Commercial
6.2.x6.2.19OSS
6.2.x6.2.18.1Commercial
6.1.x6.1.28Commercial only
5.3.x5.3.49Commercial 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 ObjectMapper to 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 LineAffected Range
7.0.x7.0.0 through 7.0.7
6.2.x6.2.0 through 6.2.18
6.1.x6.1.0 through 6.1.27
5.3.x5.3.0 through 5.3.48

The advisory warns that unsupported versions are also vulnerable. A vulnerable configuration requires:

  • An application using MappingJackson2MessageConverter or JacksonJsonMessageConverter for JMS message processing
  • The converter configured with a typeIdPropertyName that 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:

CVEProjectSeverityIssue
CVE-2026-41855Spring FrameworkHighJMS deserialization
CVE-2026-40983MicrometerHighgRPC server DoS
CVE-2026-40984MicrometerHighHTTP server DoS
CVE-2026-41715Reactor NettyMediumCredential leakage on protocol downgrade
CVE-2026-41863Spring AIMediumAnthropic Skills API file write
CVE-2026-41705Spring AIHighExpression injection in MilvusVectorStore
CVE-2026-41712Spring AIHighCross-user data leakage via ChatMemory
CVE-2026-41713Spring AIHighPrompt injection via memory poisoning
CVE-2026-40981Spring Cloud ConfigHighGCP 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

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization