Spring4Shell (CVE-2022-22965) is a critical remote code execution vulnerability in the Spring Framework that sent security teams scrambling in late March 2022, arriving less than four months after Log4Shell had already tested the industry's incident-response muscle. The name was a deliberate echo of that earlier crisis, and for good reason: Spring4Shell CVE-2022-22965 allowed an unauthenticated attacker to achieve full remote code execution on vulnerable applications by abusing Spring's data-binding mechanism to manipulate the Java class loader and ultimately write a malicious file to disk. Given Spring's ubiquity in enterprise Java applications, the blast radius was enormous, and proof-of-concept exploit code leaked publicly before an official patch was even available.
This post breaks down the affected versions, the CVSS and threat-intelligence context, the technical root cause, the disclosure timeline, and concrete remediation guidance -- along with how Safeguard helps teams catch issues like this before they ever reach production.
What Is Spring4Shell CVE-2022-22965?
Spring4Shell refers to a remote code execution flaw in the core Spring Framework's data-binding functionality. It is tracked as CVE-2022-22965 and is distinct from a separate, coincidentally timed vulnerability in Spring Cloud Function (CVE-2022-22963), which was also disclosed the same week and briefly caused confusion in early reporting. CVE-2022-22965 specifically affects the spring-webmvc and spring-webflux modules and their handling of HTTP parameter binding.
At a high level, the vulnerability lets an attacker send a specially crafted HTTP request with parameter names that reach into an object's class metadata -- effectively a form of Java class loader manipulation -- to reconfigure logging components inside an embedded Apache Tomcat server. The end result, in the classic exploit chain, is the creation of a JSP web shell on the server's file system, giving the attacker arbitrary command execution.
Affected Versions and Components
Not every Spring application was exploitable, and the specific prerequisites mattered a great deal for triage. According to the official Spring advisory, the vulnerability requires all of the following to line up:
- JDK 9 or higher
- Apache Tomcat as the Servlet container (either standalone or embedded)
- Packaging as a traditional WAR deployment (not the default executable/embedded JAR that most Spring Boot apps ship as)
- A dependency on spring-webmvc or spring-webflux
The vulnerable Spring Framework version ranges were:
- Spring Framework 5.3.0 to 5.3.17
- Spring Framework 5.2.0 to 5.2.19
- Older, unsupported Spring Framework versions were also considered likely vulnerable
The Spring team fixed the issue in Spring Framework 5.3.18 and 5.2.20. Because Spring Boot applications commonly embed Tomcat and are typically packaged as executable JARs rather than WARs, many default Spring Boot setups were not directly exploitable via the primary attack chain -- but this nuance was frequently misunderstood in the early days of disclosure, and any thorough spring boot vulnerability analysis had to walk through each application's actual packaging and deployment model rather than relying on the framework version alone. Spring Boot 2.5.12 and 2.6.6 were also released with an additional safeguard (an auto-configured disallowedFields restriction) to reduce exposure even in non-WAR deployments.
CVSS, EPSS, and KEV Context
CVE-2022-22965 was rated CVSS 3.1 base score 9.8 (Critical), reflecting a network-exploitable vulnerability requiring no privileges or user interaction and resulting in complete compromise of confidentiality, integrity, and availability. That severity, combined with how widely Spring is embedded across enterprise Java stacks, is what made this one of the most consequential Spring framework RCE disclosures in recent memory.
The vulnerability was added to CISA's Known Exploited Vulnerabilities (KEV) catalog shortly after disclosure, confirming that it was being actively exploited in the wild rather than remaining theoretical. Its EPSS (Exploit Prediction Scoring System) probability has consistently sat near the top of the scale since disclosure, consistent with the rapid, mass internet-wide scanning activity that security researchers observed within hours of the proof-of-concept leaking -- a pattern very similar to what followed Log4Shell.
Root Cause: Class Loader Manipulation Through Data Binding
The technical root cause of Spring4Shell is, in many ways, a story about an old bug coming back to life. Spring had previously addressed a conceptually similar issue years earlier under CVE-2010-1622, which involved attackers manipulating an object's class.classLoader property through Spring's data-binding (WebDataBinder) feature. The original fix blocked binding to properties beginning with class.*.
However, with the introduction of the JDK 9+ module system, the object graph reachable from a bound object changed. Instead of reaching the class loader directly through class.classLoader, an attacker could instead traverse through class.module.classLoader -- a path that the original, narrower blocklist did not anticipate. This is the essence of the java class loader manipulation at the heart of the bug: Spring's parameter binder happily walked nested getters/setters on request parameters, and the JDK 9 module object reopened a path to the same dangerous class loader reference the 2010 fix had tried to close off.
From there, the practical exploit chain (as demonstrated in public proof-of-concept code) worked roughly as follows:
- The attacker sends a POST request with parameter names crafted to traverse
class.module.classLoader.someProperty. - Spring's binder walks this chain and permits the attacker to reach and modify properties on Tomcat's
AccessLogValvelogging component -- specifically things like the log pattern, log file suffix, and directory. - By setting these properties, the attacker points Tomcat's access logging at a location inside the web root and shapes the log format so that attacker-controlled request data (also sent in the same or a follow-up request) gets written into the log file as valid JSP code.
- The attacker then requests the resulting log file, which Tomcat now serves and executes as a JSP web shell, yielding arbitrary remote code execution on the server.
This chain is a good illustration of why data-binding frameworks require careful allowlisting: the vulnerability wasn't a memory-safety bug or a classic injection flaw, but a case of an overly permissive object graph traversal being repurposed to reconfigure trusted infrastructure components already running inside the process.
Timeline
- Late March 2022 -- Screenshots and early proof-of-concept exploit details for what would become CVE-2022-22965 began circulating publicly (reportedly first posted, then deleted, on a Chinese-language security research platform) before an official advisory or patch existed, making this effectively a public zero-day for a brief window.
- March 29-30, 2022 -- Security researchers and vendors, including VMware's Spring team, raced to confirm the vulnerability, and mass internet scanning for vulnerable Spring endpoints began almost immediately as the PoC spread.
- March 31, 2022 -- Spring officially published its security advisory alongside patched releases: Spring Framework 5.3.18 and 5.2.20, plus companion Spring Boot releases (2.5.12 and 2.6.6) with additional defense-in-depth configuration. CVE-2022-22965 was formally assigned and published.
- Following weeks -- CISA added the vulnerability to its KEV catalog, and multiple vendors reported observing active exploitation attempts, including opportunistic scanning and deployment of web shells and cryptominers against unpatched, internet-facing Spring applications.
Remediation Steps
Because the exploit chain has several dependencies, remediation can be layered depending on what you can patch immediately versus what requires more validation time:
- Upgrade Spring Framework first. Update to Spring Framework 5.3.18 or later (5.3.x line) or 5.2.20 or later (5.2.x line). If you're on Spring Boot, upgrade to 2.5.12+ or 2.6.6+, which pull in the fixed Spring Framework versions.
- Patch or upgrade Apache Tomcat. Tomcat itself shipped fixes (versions such as 10.0.20, 9.0.62, and 8.5.78) that independently mitigate the exploitation path by changing how parameter names are handled, providing defense-in-depth even against unknown variants of the binding issue.
- Restrict WebDataBinder fields as an interim mitigation. If immediate upgrades aren't possible, add a global
@InitBinderthat callsdataBinder.setDisallowedFields("class.*")(or, more robustly, an explicit allowlist of bindable fields) across controllers to block the dangerous property paths. - Review packaging and deployment. Confirm whether your applications are deployed as WAR files on external Tomcat versus embedded, executable JAR Spring Boot apps -- this materially affects real-world exploitability and should inform patch prioritization.
- Upgrade the JDK where feasible, but don't rely on it alone. JDK version is a precondition for this specific chain, but it is not a substitute for patching Spring and Tomcat, since other exploitation variants and future related issues may not share the same JDK dependency.
- Hunt for indicators of compromise. Search web-accessible directories (especially inside the web root) for unexpected
.jspfiles, review Tomcat access logs for anomalous entries or unexpected log configuration changes, and check for newly created log files with suspicious naming or content. - Add WAF/IPS signatures as a stopgap. Rules blocking request parameters containing patterns like
class.module.classLoadercan reduce exposure while patching is rolled out, though this should never be treated as a permanent fix.
How Safeguard Helps
Spring4Shell CVE-2022-22965 is a textbook case for why software supply chain visibility has to extend deep into the dependency tree, version pinning, and deployment configuration -- not just a top-level "is Spring Framework in our SBOM" check. Safeguard continuously maps every service's real dependency graph, including transitive Spring, Spring Boot, and Tomcat versions, so when a vulnerability like this breaks, your team gets an immediate, accurate answer to "which of our applications are actually exposed" rather than a noisy list of every repository that merely imports Spring somewhere.
Because exploitability here hinged on packaging (WAR vs. embedded JAR) and runtime environment (JDK version, Tomcat version), Safeguard correlates SBOM data with build and deployment metadata to separate applications that are genuinely at risk from those that only look risky on paper. That context lets security and platform teams prioritize patching for internet-facing, WAR-deployed, Tomcat-backed services first, instead of burning incident-response cycles on every repository that happens to reference spring-webmvc.
Safeguard also tracks CISA KEV status and EPSS trends alongside your internal exposure data, so newly weaponized vulnerabilities like Spring4Shell are automatically flagged against the assets that matter, with remediation guidance surfaced directly to the teams that own the affected code. When the next framework-level zero-day inevitably surfaces, that combination of accurate dependency mapping, deployment-aware context, and real-time threat intelligence is what turns a chaotic, all-hands scramble into a scoped, prioritized patching effort.