Skip to main content
Offensive360

Spring4Shell — Critical Remote Code Execution in Spring Framework (CVE-2022-22965)

Spring4Shell is a critical RCE vulnerability (CVSS 9.8) affecting Spring MVC on JDK 9+. Here's what it is, whether you're affected, and how to patch it immediately.

Offensive360 Security Research Team | | Vulnerability Research
SpringJavaRCECVE-2022-22965Spring4Shellcritical vulnerability

On March 31, 2022, the Spring team disclosed CVE-2022-22965 — a critical remote code execution vulnerability in the Spring Framework affecting applications running on Java 9 or higher. The vulnerability was quickly named “Spring4Shell” by the community, drawing comparisons to Log4Shell due to its potential impact.

CVSS Score: 9.8 (Critical)

What Is Spring4Shell?

Spring4Shell exploits the way Spring MVC’s data binding feature handles Java class introspection. When a Spring controller accepts arbitrary request parameters via @ModelAttribute or direct binding, an attacker can craft parameters that access the class loader through the class hierarchy and ultimately write arbitrary files to the server.

The attack path: user-supplied HTTP parameters → Spring’s data binding → Class.getClassLoader() → write a JSP webshell → remote code execution.

Are You Affected?

You are vulnerable if ALL of the following are true:

  1. Running Spring Framework 5.3.0–5.3.17 or 5.2.0–5.2.19
  2. Running on Java Development Kit 9 or later (critical: JDK 8 is NOT affected)
  3. Deployed as a WAR file to Apache Tomcat (not as a Spring Boot embedded server JAR)
  4. Using spring-webmvc or spring-webflux

You are NOT affected if:

  • Running on JDK 8 (important: many Spring Boot apps still target JDK 8)
  • Running as a Spring Boot fat JAR with embedded Tomcat
  • Running on a non-Tomcat container (the most serious exploitation vectors require Tomcat’s specific class structure)
  • Running a patched version of Spring Framework (5.3.18+ or 5.2.20+)

Proof-of-concept code became publicly available quickly, making this a race to patch.

Patching

Upgrade Spring Framework

The fix is in Spring Framework 5.3.18 and 5.2.20:

<!-- Maven: set the Spring Framework version -->
<properties>
    <spring-framework.version>5.3.18</spring-framework.version>
</properties>
// Gradle
ext['spring-framework.version'] = '5.3.18'

Upgrade Spring Boot

If using Spring Boot, upgrading to these versions includes the patched Spring Framework:

  • Spring Boot 2.6.6 (includes Spring 5.3.18)
  • Spring Boot 2.5.12 (includes Spring 5.3.18)
<!-- Maven -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.6</version>
</parent>
// Gradle
plugins {
    id 'org.springframework.boot' version '2.6.6'
}

Upgrade Apache Tomcat

Patched Tomcat versions also mitigate the attack:

  • Tomcat 10.0.20
  • Tomcat 9.0.62
  • Tomcat 8.5.78

Workaround (If Immediate Patching Isn’t Possible)

If you cannot patch immediately, you can add a WebDataBinder initializer to block the dangerous properties:

@ControllerAdvice
public class SecurityBinderAdvice {
    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
        String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
        dataBinder.setDisallowedFields(denylist);
    }
}

This workaround blocks the class attribute binding that enables the attack, but upgrading to the patched version is strongly preferred.

How to Check Your Exposure

Quick check for Maven projects:

# List all Spring Framework versions in your dependency tree
mvn dependency:tree | grep spring-core

# For Gradle
./gradlew dependencies | grep spring-core

For containerized deployments, check all running images:

# Find Spring apps in running containers
docker ps -q | xargs -I {} docker exec {} find / -name "spring-core-*.jar" 2>/dev/null

Active Exploitation

Proof-of-concept exploit code was published within hours of disclosure. Security firms observed active exploitation attempts within days, with attackers attempting to deploy webshells via the vulnerability.

Treat this as an emergency patch — prioritize all WAR-based Spring applications running on JDK 9+ immediately.

Difference from Log4Shell

Spring4Shell requires more specific conditions (JDK 9+, WAR deployment, Tomcat) compared to Log4Shell, which affected virtually any Java application using Log4j 2.x. However, the exploitability is comparable when those conditions are met.

Both vulnerabilities underscore the importance of maintaining an accurate software inventory and having a fast patch process for critical vulnerabilities in widely-used Java libraries.

Written by Offensive360 Security Research Team

Find vulnerabilities before attackers do

Run Offensive360 SAST and DAST against your applications to catch security issues early.