In late March 2022, the Java ecosystem was rocked by a critical remote code execution vulnerability in the Spring Framework, quickly dubbed "Spring4Shell" for its resemblance in impact — though not in root cause — to the Log4Shell vulnerability that had dominated headlines only months earlier. Tracked as CVE-2022-22965, the flaw allows an unauthenticated attacker to achieve full remote code execution on vulnerable applications by sending a single crafted HTTP request. Given that Spring is one of the most widely used application frameworks in enterprise Java, and that the vulnerable code path sits in core data-binding logic used by nearly every Spring MVC application, the potential blast radius was enormous. Within days of disclosure, mass internet scanning and active exploitation attempts were observed, and the vulnerability was added to CISA's Known Exploited Vulnerabilities (KEV) catalog.
What Is Spring4Shell?
CVE-2022-22965 is a class-loader manipulation vulnerability rooted in Spring's data-binding mechanism. Spring MVC and Spring WebFlux applications automatically bind incoming HTTP request parameters to Java objects using a component called DataBinder. This binder walks the property graph of a target object and, unless explicitly restricted, allows nested property access — including properties exposed transitively through getClass().
The vulnerability is conceptually related to a much older issue, CVE-2010-1622, which Spring had partially mitigated years earlier. Attackers rediscovered that on JDK 9 and above, the ClassLoader object exposes properties (via getClassLoader()) that were not present or reachable the same way on JDK 8, reopening the class-loader manipulation path that the original fix had closed for older JDK versions. By sending a request with parameters like class.module.classLoader.resources.context.parent.pipeline.first.pattern, an attacker can walk through the Tomcat class loader hierarchy and, on servers using Apache Tomcat as the servlet container with WAR-based (non-embedded) deployment, overwrite AccessLogValve properties. Combined with a second crafted request, this allows the attacker to write a malicious JSP web shell to disk within the application's web root, and a third request to invoke it — yielding arbitrary remote code execution with no authentication required.
Affected Versions and Components
Exploitation of CVE-2022-22965 requires a specific combination of conditions:
- JDK version: 9 or higher (JDK 8 is not exploitable via this exact chain, since the relevant
ClassLoadergetters behave differently) - Spring Framework: versions prior to 5.3.18 and prior to 5.2.20
- Spring Boot: versions prior to 2.5.12 and prior to 2.6.6 (Spring Boot bundles Spring Framework, so applications inherit the vulnerability transitively)
- Servlet container: Apache Tomcat (the disclosed proof-of-concept specifically abuses Tomcat's
AccessLogValve; other containers may present different or non-exploitable variants) - Packaging: Traditional WAR deployment to an external servlet container. Applications using Spring Boot's default embedded Tomcat and executable JAR packaging are generally not exploitable via the published PoC, though the underlying data-binding weakness still exists and other exploitation primitives were an open question at disclosure time.
- Dependency: Use of
spring-webmvcorspring-webfluxwith parameter binding via@ModelAttribute-style objects (or annotated request-mapping handlers relying on POJO binding), rather than exclusively@RequestBodywith JSON deserialization.
Because so many Spring Boot starter templates default to embedded Tomcat with JAR packaging, a meaningful share of Spring Boot applications were not exploitable via the exact published chain — but a substantial population of traditional enterprise deployments (WAR files deployed to standalone Tomcat, WebLogic, or WebSphere instances) matched the vulnerable profile precisely, and the underlying data-binding flaw was serious enough that Spring and downstream vendors treated it as universally patch-worthy regardless of deployment topology.
Severity: CVSS, EPSS, and KEV Status
CVE-2022-22965 was assigned a CVSS v3.1 base score of 9.8 (Critical), reflecting network-exploitable, unauthenticated, low-complexity access resulting in complete compromise of confidentiality, integrity, and availability. Its EPSS (Exploit Prediction Scoring System) score climbed rapidly after disclosure, sitting among the higher percentiles observed for any CVE that year, driven by the near-immediate availability of public proof-of-concept exploit code and automated scanning activity. The vulnerability was added to the CISA Known Exploited Vulnerabilities catalog shortly after disclosure, with a mandated remediation deadline for U.S. federal agencies — a strong signal that exploitation in the wild was confirmed, not merely theoretical.
Timeline
- March 29, 2022: A researcher published a since-deleted proof-of-concept on GitHub after observing unusual, unpatched behavior in Spring's
RequestMappingHandlerAdapter. Screenshots and partial code circulated on social media and security mailing lists before an official advisory existed, causing significant confusion — some outlets and early write-ups conflated it with the unrelated Spring Cloud Function vulnerability, CVE-2022-22963, disclosed the same week. - March 30, 2022 (~30 hours after leak): VMware (then maintainer of Spring) released Spring Framework 5.3.18 and 5.2.20, along with an official advisory confirming the vulnerability and assigning CVE-2022-22965.
- March 31, 2022: Spring Boot 2.6.6 and 2.5.12 were released, pulling in the patched Spring Framework versions for downstream consumers.
- Early April 2022: Mass scanning and exploitation attempts were reported by multiple threat intelligence teams within 24–48 hours of patch release, including deployment of the Mirai botnet and cryptomining payloads against unpatched internet-facing servers.
- Mid-April 2022: CISA added CVE-2022-22965 to its KEV catalog, and multiple national CERTs issued advisories urging immediate patching.
Remediation Steps
- Upgrade Spring Framework to 5.3.18+ or 5.2.20+, and Spring Boot to 2.6.6+ or 2.5.12+, wherever it is a direct or transitive dependency. Because most organizations consume Spring Framework transitively through Spring Boot, verify the resolved version in your build (
mvn dependency:treeor./gradlew dependencies), not just the declared Boot version, since some parent POM overrides or dependency management blocks can pin an older Spring Framework release even after bumping Boot. - Apply the interim workaround if you cannot patch immediately. Spring's advisory documents a mitigation using
WebDataBinder.setDisallowedFields()to block binding of theclass.*property path globally, via aControllerAdvicebean. This closes the specific exploitation chain without requiring a full framework upgrade, and is appropriate as a stopgap — not a long-term substitute for patching. - Downgrade JDK exposure where feasible, though this is not a substitute for patching: pinning to JDK 8 removes the specific
ClassLoaderreachability path used in the public PoC, but other unknown variants may exist and JDK downgrades carry their own support and compliance tradeoffs. - Audit servlet container configuration. If running Tomcat with WAR deployment, review
AccessLogValveand logging configuration for signs of tampering (unexpected log file paths, suffixes, or patterns), and check the web root for unauthorized.jspfiles with recent modification timestamps as an indicator of prior compromise. - Deploy WAF/IPS signatures as a compensating control while patches roll out — filtering request parameters containing
class.module.classLoader,class.classLoader, or similar nested property paths at the edge blocked the published exploitation chain, though attackers quickly began testing encoding and obfuscation variants to evade naive pattern matches. - Inventory every exposed Spring application, not just customer-facing ones. Internal admin panels, partner APIs, and staging environments running vulnerable Spring versions are equally exploitable and are frequently the ones patched last.
- Review logs retroactively for the multi-request exploitation pattern (probe request, JSP-write request, shell-invocation request) covering the window between public PoC leak (March 29) and your organization's patch deployment date, since attackers scanned aggressively during that gap.
How Safeguard Helps
Spring4Shell is a textbook case for why patch prioritization has to be reachability-aware rather than version-match-only: countless Spring Boot services technically contained the vulnerable framework version but were never exploitable because they used embedded Tomcat with JAR packaging or never bound untrusted parameters through vulnerable data-binding paths. Safeguard's reachability analysis traces actual call paths from network-facing entry points down into vulnerable Spring binding logic, so security teams can immediately distinguish genuinely exploitable services from theoretically-vulnerable-but-inert ones, cutting remediation triage time dramatically. Griffin, Safeguard's AI-driven analysis engine, correlates dependency graphs, deployment metadata (packaging type, servlet container, JDK version), and runtime context to flag which of your Spring services match the true exploitation profile for CVE-2022-22965 and similar chained vulnerabilities. Safeguard's SBOM generation and ingestion capabilities give you continuous, accurate visibility into every transitive Spring Framework version across your fleet — including versions pinned by parent POMs that a surface-level Boot version check would miss — so the next Spring4Shell-class disclosure doesn't require a manual dependency-tree spelunking exercise. And where remediation is confirmed necessary, Safeguard can generate auto-fix pull requests that bump Spring Framework and Spring Boot to patched versions across affected repositories in bulk, turning a fleet-wide emergency patch cycle into a review-and-merge workflow instead of a scramble.