Another day, another zero-day Remote Code Execution exploit unleashed on Java systems.
Just when you thought it was safe to go back to the water after the Log4Shell exploit a mere four months ago, now the Spring4Shell (or SpringShell) exploit is emerging as another threat to enterprise systems.
The root cause is an issue in the commonly used open-source Java library Spring. Spring has been used by enterprise developers (including yours truly) for many years to simplify Java development and deployment.
Spring4Shell does not appear to be as much of a threat as Log4Shell at this writing, since it is applicable only to users of specific Spring modules and under certain deployment conditions. Log4Shell has a much larger set of targets, since it could infect many Java systems just because they used the popular log4j framework. That being said, Spring4Shell is still a critical RCE vulnerability.
In this post, we’ll address three primary questions.
- Are Solo.io products vulnerable to Spring4Shell?
- Are my systems fronted by Gloo Edge and Gloo Mesh Gateway vulnerable to Spring4Shell?
- If so, how can I remediate those risks? Can Gloo Edge help?
Let’s start with the easiest question first. Solo.io products are NOT vulnerable to Spring4Shell. Solo.io product microservices are implemented most commonly using Go. Envoy proxy is a key open source component deployed with all Solo.io products and is implemented in C++. Consequently, none of them have any Spring dependencies.
But what about my systems?
The fact that Solo.io products themselves aren’t exposed by Spring4Shell is a nice first step. But that doesn’t fully address the second question of whether a customer’s systems that use Gloo Edge as their API gateway are vulnerable.
There are multiple recent CVEs that are loosely associated with Spring4Shell. The one garnering the most attention as of this writing is CVE-2022-22965, which is rated Critical. This exploit takes advantage of a vulnerability in the Spring data binding feature to potentially allow an attacker to execute arbitrary code on a compromised system. It targets applications using particular Spring frameworks (spring-webmvc or spring-webflux), and that are deployed in a Tomcat container as a WAR.
Another related CVE (CVE-2022-22963) targets applications that use the Spring Cloud module. It takes advantage of the Event Routing feature that allows users to pass in routing expressions via a specific HTTP header whose value could contain malicious code.
Good examples of both of these exploits are available in this Fastly post.
Check the resources linked in this section to determine for sure whether you’re vulnerable to Spring4Shell.
I might be vulnerable. How do I respond?
If your systems are potentially at-risk, there are a number of avenues to mitigate that.
- Update to the latest patched Spring framework versions. Both the Spring Core and the Spring Cloud framework have already released patched versions that shut down these attack vectors, as shown in the figure below.
- Initiate a vulnerability scan. There are both open source and enterprise tools that can thoroughly analyze your systems for vulnerabilities to Spring4Shell (and a hundred others). At Solo.io, we’re particularly fond of our partner Snyk, which offers scanning tools in both free and paid flavors.
In addition to these two approaches, Gloo Edge can help! The Enterprise edition provides Web Application Firewall support with a widely used framework called ModSecurity, which began life as an Apache project. From the Gloo Edge documentation:
“API Gateways act as a control point for the outside world to access the various application services running in your environment. A Web Application Firewall offers a standard way to inspect and handle all incoming traffic. ModSecurity is one such firewall. ModSecurity uses a simple rules language to interpret and process incoming http traffic.”
The most popular ModSecurity ruleset is sponsored by OWASP and called CoreRuleSet, and it is packaged for use with Gloo Edge Enterprise. The CRS community will doubtless produce rules to thwart Spring4Shell attacks, although none has been published as of this writing. But we don’t need to wait for that to happen.
Later in this post, we will create our own custom ModSecurity rules to block any potentially malicious traffic trying to exploit the Spring4Shell vulnerability. We will implement this in a pair of simple ModSecurity rules, and we will deploy it in a Gloo Edge Gateway component. In this way we can protect any service fronted by that Gateway without modifying the underlying application code.
Example: Use Gloo Edge to block Spring4Shell attacks
We’ll build and test an example to show how you can use Gloo Edge to protect systems that are vulnerable to Spring4Shell attacks.
If you’d like to follow along in your own environment, all you’ll need is a Kubernetes cluster and associated tools like kubectl
. We’re using a GKE cluster to perform our testing, but any proper Kubernetes cluster should work fine. In addition, you’ll need an instance of Gloo Edge Enterprise to complete this guide. Installation instructions are here. If you don’t have access to a Gloo Edge Enterprise license key, you can request a free trial here.
We’ll use the popular httpbin service as a stand-in for the systems we need to protect. We’ll then build a simple Gloo Edge VirtualService
with no protection against Spring4Shell and simulate some common attack vectors. Finally, we’ll apply simple ModSecurity rules to our Web Application Firewall and demonstrate how those attacks are repulsed with Gloo Edge.
Establish a target service
HTTPBIN is a great little REST service that can be used to test a variety of http operations and echo the request and response elements back to the consumer. We’ll use it throughout this exercise as being representative of systems that are potentially vulnerable to Spring4Shell attacks. First, we’ll install a Gloo Edge Upstream
to our cluster that acts as a facade for the public httpbin service.
Run this command to apply the Upstream
to your Kubernetes cluster:
You should see this response
Build a routing policy
We’ll next create a simple Gloo Edge VirtualService
to route any request that is presented to our API gateway to the httpbin service.
Apply that VirtualService
using this command:
Expect this response in return:
The initial service has a security problem!
The attack vectors for the Spring4Shell vulnerabilities that we’re considering here are slightly different. Let’s explore each in turn.
Spring Cloud attack
For the Spring Cloud vulnerability, the attack contains malicious code in a particular request header spring.cloud.function.routing-expression
. See this exploit code for an example. In unpatched versions of Spring Cloud, this header is not validated properly and will be executed by the Spring Expression Language (SpEL) interpreter.
We’ll use curl
to simulate the attack by passing in the malicious code via the SpEL header through the VirtualService
we created in the previous section:
Note that this command will fail if you don’t have the glooctl
utility installed on your workstation.
The /anything
endpoint of httpbin simply echoes back the request headers passed into it.
You can expect a response like the one below. Note in particular the routing-expression
entry in the headers
response. Our malicious code was accepted without an error. If httpbin were based on Spring Cloud, which it isn’t, then we might have real exposure to this attack.
Spring MVC and WebFlux attack
For the Spring MVC and WebFlux vulnerability, the attacker POSTs to a vulnerable server a request that manipulates the Java classLoader into using an alternative location to load its malicious code. One fingerprint of this attack is that it POSTs an argument named class.module.classLoader.resources.context.parent.pipeline.first.pattern
as shown in this example exploit.
We’ll use curl
to simulate the attack by passing in the malicious code via the POST body of the request:
You can expect a response like the one below. Note in particular that our classLoader entry was accepted as part of the request. If httpbin were based on Spring MVC or WebFlex and was deployed as a WAR on a Tomcat container, then we might have real exposure to this attack.
Integrate a simple WAF policy
We’ll craft a policy using two simple WAF rules, one for each of the attack vectors in the previous section. Here is the rule we’ll use to block the Spring Cloud attack.
We won’t attempt a ModSecurity rule authoring tutorial here. There are better sources for that information, like the official community GitHub site.
But let’s examine briefly what this rule does. Line 1 identifies ModSec variables we want to match. In this case there’s just one: REQUEST_HEADERS_NAMES
. This expands to a list of all HTTP header names (not values) associated with the request.
Line 2 is the condition that is applied to the variables listed in Line 1. In this case, we’re using the routing-expression
header as the fingerprint of this attack. That is the header that SpEL uses to find code to execute. Note that we are assuming no legitimate uses for this header in external user requests, which seems like a safe assumption for typical applications.
Finally, Line 3 defines the action to be taken when the rule is matched. In this case, if we see this header, we are denying the request and passing back a 403 Forbidden
error code.
The second rule to block the Spring MVC and WebFlux attack exhibits a similar structure.
In this case, the primary difference is that we are looking for the attack fingerprint in the request body rather than in the set of request header names. And as before, we implicitly assume that there are no legitimate uses of the classLoader
argument above in typical application requests.
We’ll apply both of these rules at the Gateway
level of Gloo Edge. That means that even though we only have one service being managed by this gateway, the rule would equally apply if we had 100 services deployed behind that same Gateway
.
This highlights one of the core strengths of Gloo Edge, the ability to apply sophisticated policies once and have them automatically applied to multiple backend services, with no changes to the target services. This is not only true of WAF policies, but also complex authNZ policies too. See our partner Snyk’s recent post about normalizing authentication policies across a variety of backend services.
Here is the full Gateway
implementation that we’ll apply to our cluster. Note in particular the waf:
configuration.
We’ll apply the new Gateway
configuration to our cluster using kubectl
:
Expect a response like this:
Now let’s thwart some EVIL!
Can our new Gateway
configuration defeat a sampling of Spring4Shell attacks? We’ll answer that by retrying our earlier “attacks” against our service.
Spring Cloud attack
We’ll use curl
to simulate the Spring Cloud attack we used before with the unprotected service. Recall that the service fulfilled the request with no problems, which would have created a problem had the backend service been vulnerable to Spring4Shell.
But observe the difference with our WAF protection in place. The malicious request is now rejected with a 403 Forbidden
error.
The Spring Cloud attack is defeated!
Spring MVC and WebFlux attack
Now we’ll repeat the simulated Spring MVC and WebFlux attack:
The response shows that the ModSec rule is again doing its job as expected:
The MVC and WebFlux attack is defeated!
Clean up
Would you like to reset your environment to its previous state before beginning this exercise? It’s simple. Just issue the following commands to reset the Gateway
to not use our WAF policy, and to delete the Upstream
and VirtualService
we created.
Learn more
In this post, we confirmed that users of Solo.io products like Gloo Edge do not need to be concerned about those products being vulnerable to Spring4Shell attacks. We also demonstrated how to use the Gloo Edge Web Application Firewall to block Spring4Shell attacks against your own systems with a couple of simple ModSecurity rules. In other words, you can protect against attacks like this at the API gateway level without waiting on updates to the upstream applications.
IMPORTANT NOTE: These are still early days for the Spring4Shell exploit. As of this writing, our collective understanding of how best to protect against it is evolving. Do not accept our simple rule in this post as the final word on the subject. Please do not deploy these sample rules to production without conducting your own due diligence. We recommend following developments in security-focused communities like CoreRuleSet to keep up with the latest best practices.
All resources used to build the example in this post are available on GitHub.
Do you want to explore further how Solo and Gloo Edge can help you secure your microservice and legacy environments?
- Check out our December 2021 blog post on using Gloo Edge to thwart the Log4Shell attack.
- Check out Gloo Edge product information and documentation.
- Reach out to Solo experts on the Solo.io Slack community and particularly the #gloo-edge channel.
- Request a live demo or trial.
- See video content on the solo.io YouTube channel.