The Spring Shell vulnerability, widely known as Spring4Shell and tracked as CVE-2022-22965, is a remote code execution flaw in the Spring Framework's data-binding mechanism. It surfaced publicly in March 2022 through a since-deleted proof-of-concept, and within days security teams everywhere were scrambling to assess exposure across Java codebases built on Spring MVC.
What Made Spring4Shell Exploitable?
The core issue was in how Spring's data binder handles class property references during parameter binding. Under specific conditions — Spring MVC or Spring WebFlux applications running on JDK 9 or later, deployed as a traditional WAR to a servlet container like Tomcat, using Spring's data binding features — an attacker could manipulate the class.module.classLoader property chain through a crafted HTTP request. This allowed writes to parts of the runtime that shouldn't be reachable through user input, ultimately enabling remote code execution.
It's worth being precise about the preconditions because they mattered a lot for real-world impact. Applications packaged as executable JARs with an embedded servlet container (the default for most modern Spring Boot apps) were generally not exploitable through the same path, which meant the blast radius was narrower than the initial panic suggested — but far from zero, since traditional WAR deployment on external Tomcat remains common in enterprise Java shops.
How Was It Different From the Original "Log4Shell" Panic?
The timing amplified the reaction. Spring4Shell surfaced just months after Log4Shell (CVE-2021-44228), and the initial reports conflated the two — some early coverage implied a Log4j-scale, unauthenticated, trivially exploitable RCE across virtually any Java application. That wasn't accurate. Spring4Shell had real but narrower preconditions, and its practical severity, while serious, was lower than Log4Shell's essentially unconditional exploitability.
That said, "narrower preconditions" still described a large number of real production deployments, and organizations running Spring MVC on JDK 9+ with WAR deployment needed to patch quickly regardless of the nuance.
What Was the Actual Fix?
Spring released patched versions — Spring Framework 5.3.18 and 5.2.20, and corresponding Spring Boot updates — that closed the data-binding path that allowed the classloader manipulation. Organizations that couldn't immediately patch were advised to apply mitigations like disabling the vulnerable data binding pattern or upgrading the JDK version being used, though patching the framework version remained the definitive fix.
A related, separately tracked issue around the same period involved spring-security-crypto handling of certain cryptographic operations — a good reminder that "Spring had a vulnerability" often needs the specific module and CVE number attached before you can assess actual impact, since the Spring ecosystem spans dozens of independently versioned modules.
What Should You Actually Check Today?
If you're auditing legacy Java applications now, check for Spring Framework versions predating 5.3.18/5.2.20 still in WAR-deployed, JDK 9+ environments. Dependency scanning against a CVE database will surface the vulnerable version automatically, but understanding the actual exploitation preconditions matters for prioritization — a Spring app packaged as a self-contained Spring Boot JAR with an embedded Tomcat instance carries meaningfully lower risk from this specific CVE than one deployed as a traditional WAR.
This is a good general lesson for how to triage any framework-level CVE: read past the CVSS score to the actual preconditions, because they determine whether your specific deployment pattern is exposed. Our SCA product flags vulnerable dependency versions automatically, but pairing that with an understanding of your deployment architecture is what turns a raw CVE list into a prioritized patch plan.
FAQ
Is Spring4Shell the same as Log4Shell?
No. They're unrelated vulnerabilities in different projects (Spring Framework vs. Log4j) that happened to surface within months of each other, which caused significant confusion in early coverage.
What Spring Framework versions fix CVE-2022-22965?
5.3.18 and 5.2.20, along with the corresponding Spring Boot patch releases that pulled in the fixed framework version.
Does upgrading the JDK version alone fix Spring4Shell?
It mitigates one specific exploitation path (related to JDK 9's module system exposing the vulnerable classloader property), but upgrading the Spring Framework version is the actual fix recommended by the maintainers.
Are Spring Boot JAR deployments completely safe from this CVE?
They're generally not exploitable through the documented attack path, but "not exploitable through the known path" is different from "definitively unaffected" — patching remains the recommended action regardless of deployment style.