Anatomy of the Spring4Shell vulnerability and how to prevent its effects—and those of similar vulnerabilities

Spring4Shell is a critical vulnerability in the Spring Framework, which emerged in late March 2022. Because 60% of developers use Spring for their Java applications, many applications are potentially affected. With a critical CVSS rating of 9.8, Spring4Shell leaves affected systems vulnerable to remote code execution (RCE).

To illustrate why Spring4Shell is such a critical vulnerability, it helps to understand how Spring works.

What is the Spring Framework?

Spring is a widely used open source Java-based framework for building web applications with the Java Enterprise Edition platform. An extension of the Spring Framework is Spring Boot, which gives developers a fast and simple way to create and configure production-ready applications. A core logic of the Spring Framework is dependency injection, which allows developers to build decoupled IT architectures.

According to a report on how organizations use Java Technologies, Spring and Spring Boot are the most popular. Further, the report lists Tomcat as the most popular Java application server. The Spring4Shell vulnerability affects all these components, as we discuss in what follows.

How do developers use the Spring Framework?

Spring enables developers to map user requests to Java objects. In the example below, we have a simple DemoObject class that contains a string attribute message.

Spring4Shell demo object
Figure 1: Web application that uses a DemoObject as its object

To map the DemoObject class to web requests, Spring provides a controller object as shown in Figure 2. An application user submits parameters through a browser, which the RequestMapping component of the Spring Framework maps to our DemoObject.

Spring4Shell demo controller
Figure 2: Spring Controller that maps the DemoObject to requests received at the server

Once Spring maps our DemoObject, we can use the message attribute as a variable in the HTML code shown in Figure 3, which gets rendered in the browser shown in Figure 4.

Spring4Shell example message HTML
Figure 3: HTML file of our demo app showing the variable ${message} mapped from our DemoObject
Spring4Shell Demo App Message
Figure 4: Demo web application, rendered with the user input “Hello to all!”

How the Spring4Shell vulnerability exposes Spring Framework apps to RCE exploitation

Understanding how the Spring Framework works is important to grasp how attackers are able to exploit the Spring4Shell vulnerability. In particular, CVE-2022-22965 affects applications running on an Apache Tomcat server as a web application archive (WAR) deployment.

The Spring Framework exposes the class member of the object the parameter is bound to, for example:


Through this exposure, attackers can write arbitrary code onto a server.

The crux of the Spring4Shell vulnerability is that the affected versions of the Spring Framework expose the class object and do not sufficiently restrict the accessible getter methods (specifically Java 9’s Class.getModule).

The following example illustrates the steps an attacker could take to exploit the Spring4Shell vulnerability.

1 Overwrite the Tomcat logging directory

Attackers can use a POST request as follows to overwrite the directory where Tomcat logging files are stored locally on the server:

POST http://localhost:8080/s4sdemo/demoapp?

2 Set the prefix and suffix of the file to store it on a server

The attacker’s POST request adds the prefix to the start of the written log file. The suffix specifies the file extension, for example:

POST http://localhost:8080/s4sdemo/demoapp?class.module.classLoader.resources.context.parent.pipeline.first.prefix=

POST http://localhost:8080/s4sdemo/demoapp?class.module.classLoader.resources.context.parent.pipeline.first.suffix=

3 Write arbitrary payload into the created file

Attackers can then write an arbitrary payload into the created .jsp file. For example:

POST http://localhost:8080/s4sdemo/demoapp? class.module.classLoader.resources.context.parent.pipeline.first.pattern=

4 Set the fileDateFormat to an empty string

The attacker can keep the custom fileDateFormat field empty since they don’t want to write a timestamp to the created filename. For example:

POST http://localhost:8080/s4sdemo/demoapp? class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

Using such steps, attackers can now exploit this setup by overwriting the logging settings through the exposed classloader and write arbitrary strings into a specified file. An attacker can use the following properties to specify the file “wtpwebapps/ROOT/shell.jsp” that contains Java code to read the server’s operating system, for example:




class.module.classLoader.resources.context.parent.pipeline.first.pattern= <% out.println(System.getProperty("")); %>

Running the demo application in debug mode shows the submitted exploit payload as shown in figure 5.

Spring4Shell demo debugger
Figure 5: The debugger shows the submitted exploit payload

5 Remotely call the created .jsp file

An attacker can then remotely call the created “shell.jsp,” which will execute the written payload and print the OS name as shown in Figure 6.

Spring4Shell example payload results
Figure 6: In our example, executing the written Java code in the shell.jsp file shows the OS name

Although this is a simple example, an attacker can write more sophisticated payloads to a server using this same method. For example, other exploit payloads that have surfaced create a web shell .jsp file. This allows an attacker to remotely execute shell commands on the server.

How can you detect and remediate the Spring4Shell vulnerability?

In a previous article on Spring4Shell, we outlined how teams can use Dynatrace Application Security to detect the actual usage of vulnerable Spring libraries in your environment. In addition to that you can use the Dynatrace Spring4Shell exporter Python script to search for all processes that fulfill the exploitability requirements (running in Apache Tomcat with a Java version 9+) via the Dynatrace application programming interface (API).

There are multiple steps you can take to prevent any harm by attackers exploiting Spring4Shell, explained in articles like the Spring Framework RCE early announcement:

  • Upgrade Spring to non-vulnerable versions 5.3.18 and 5.2.20
  • Upgrade Apache Tomcat to non-vulnerable versions 10.0.20, 9.0.62 and 8.5.78
  • Use an older version of Java (up to Java 8)
  • Change the application code to include disallowedFields containing “class.*“, “Class.*“, “*.class.*“, “*.Class.*
  • Adapt the configuration of a Web Application Firewall (WAF), if such is in place, to filter out requests containing “class.*“, “Class.*“, “*.class.*“, “*.Class.*

All these mitigations require manual intervention and time, however, which you may not have when attackers may be trying to exploit such a new vulnerability.

How Dynatrace Application Security enables automatic real-time protection

Dynatrace Application Security remediates Spring4Shell by looking at attackers’ ultimate goal: to exploit vulnerabilities such as Spring4Shell or Log4Shell. After all, attackers want to gain control of the system they’re exploiting, usually by planting some kind of back door or web shell, which allows them to execute arbitrary commands.

Executing such commands using a web shell, as shown in many Spring4Shell articles (such as the Spring4Shell Security Analysis article from LunaSec), falls into the category of command injection attacks. And as recently announced, the upcoming capability of real-time attack detection and blocking for Java enables Dynatrace Application Security to detect and also block such attacks in a generic way.

The result? Dynatrace Application Security will be able to detect and block attacks as soon as attackers try to exploit vulnerabilities such Spring4Shell by injecting commands.

Let’s look at this in action by using the Spring4Shell setup and exploit from the LunaSec article mentioned previously. In this example, Dynatrace detected the command injection attack:

Spring4Shell Dynatrace Command Injection example
Figure 7: Dynatrace real-time attack detection identifies the command injection attack via the web shell

The bottom line? Dynatrace real-time attack detection, available in the next 60 days, will not only address specific vulnerabilities but whole classes of vulnerabilities in a generic way. This approach can detect and block command injections independently without prior knowledge of the actual (zero-day) vulnerability the attacker used to inject a back door or web shell.

How to prevent attacks against the Spring4Shell vulnerability

The severity of vulnerabilities like Spring4Shell and Log4Shell highlight the need for automatic detection and remediation methods that can identify novel exploits without prior knowledge of the exploit’s specifics.

Given the wide adoption of the Spring Framework, many web applications are currently vulnerable to RCE and malicious code deployment.
Dynatrace Application Security with attack detection enables the early detection and remediation of such exploits.

How to get Dynatrace Application Security

If you are a Dynatrace customer, you can use the Application Security module for automatic runtime vulnerability analysis. Go to the Dynatrace web UI and select Vulnerabilities in the menu (separately licensed).

If you don’t use Dynatrace yet, it’s easy to get started in less than five minutes with the Dynatrace free trial. Contact us for how you can enable Dynatrace Application Security. In the meantime, have a look at our Application Security product tour.

If you are concerned about Spring4Shell’s effect on Dynatrace components, please have a look at our security alerts, specifically SpringShell CVE-2022-22965.


Christian Schwarzbauer co-authored this article.

Stay updated