← Back to Feed CACHED · 2026-07-23 03:05:15 · CACHE_KEY tenable:304671
tenable:304671 · CWE-349 · Disclosed 2026-02-04

nginx 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A race between nginx's read loop and its own TLS handshake — but only if an attacker already sits between nginx and its backend

CVE-2026-1642 is a race condition in how nginx processes upstream TLS connections. When nginx is configured as a reverse proxy to a TLS-backed upstream (HTTP/1.x, HTTP/2, gRPC, uWSGI), the event loop can process a READ event on the socket before the TLS handshake with the upstream completes. An attacker with a MITM position between nginx and its upstream server can flood the socket with plaintext HTTP during that narrow window; nginx will accept those bytes as if they came from the authenticated TLS peer. Affected: nginx 1.3.0 through 1.29.4 (both OSS and Plus). Fixed in 1.28.2 (stable) and 1.29.5 (mainline). The impact vector is VC:N/VI:H/VA:N — integrity only, no confidentiality or availability loss.

F5 rated this HIGH (CVSS v4.0 8.2) but the same vector maps to CVSS v3.1 5.9 (Medium) — a telling gap. The v4.0 score inflates because it doesn't fully weight the *upstream-side* MITM prerequisite. In practice, upstream traffic runs across a data-center fabric, VPC peering, service mesh, or private link — networks where an attacker with MITM capability already has far more damaging options (steal secrets, replace the backend outright, harvest tokens). Vendor severity is overstated for the typical enterprise deployment; MEDIUM is a truer read.

"Requires MITM on your backend-side network. If an attacker has that, upstream response injection is the least of your problems."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Obtain MITM on the nginx→upstream path

Attacker must intercept TCP traffic between the nginx reverse proxy and its TLS-enabled backend. This is the leg that runs *inside* the trust boundary — over VPC peering, an east-west VLAN, a service-mesh sidecar, or a WAN link between datacenters. Achieved via ARP spoofing on a shared L2, BGP hijack of a private ASN, compromised switch/router, or a hostile cloud tenant on shared infra.
Conditions required:
  • Layer-2 or layer-3 path insertion between proxy and upstream
  • Ability to observe the TCP handshake to the upstream in real time
Where this breaks in practice:
  • Backend traffic is almost never on a shared L2 segment an outside attacker can reach
  • Service meshes (Istio, Linkerd) and private-link fabrics remove the MITM surface
  • Anyone with this position already owns your east-west network — dozens of higher-impact attacks are available first
Detection/coverage: Network-level anomaly detection (Zeek, Suricata) may flag ARP spoofing or route flaps. Cloud provider VPC flow logs will not detect this by themselves.
STEP 02

Win the race against the TLS Client Hello

As soon as the TCP three-way handshake with the upstream completes, the attacker injects a crafted plaintext HTTP response into the socket *before* nginx's OpenSSL layer transmits the Client Hello. Because nginx processes the READ event first, those bytes are queued and later parsed as if they were the decrypted upstream response.
Conditions required:
  • Precise timing tooling — e.g., a custom scapy/nftables shim on the MITM node
  • Knowledge of the exact request pattern nginx will forward
Where this breaks in practice:
  • Race window is on the order of milliseconds
  • TLS resumption / keep-alive short-circuits the vulnerable path on subsequent requests
  • Any TLS-terminating middlebox in front of the upstream (stunnel, envoy) closes the window
Detection/coverage: No public scanner has runtime detection; Nessus 304671 is banner-only and does not confirm exploitability.
STEP 03

Inject a malicious response body / headers

The attacker crafts an HTTP/1.1 or HTTP/2 response that nginx will forward to the real client. This can be used to poison the nginx cache (proxy_cache), bypass a WAF that only inspects the client-facing leg, or smuggle cookies/CSP headers back to the browser. No confidentiality is lost — the attacker is *writing*, not reading — but downstream user sessions can be tampered with.
Conditions required:
  • proxy_cache enabled for cache poisoning to persist beyond a single request
  • Response reaches a browser or downstream service that trusts the header set
Where this breaks in practice:
  • proxy_cache_key and cache-control headers on the upstream may prevent caching
  • Downstream client validates content signatures (JWT, HTTPS pinning at browser)
  • Integrity-only impact — no code execution primitive from this bug alone
Detection/coverage: Cache-hit-ratio anomalies, unexpected Set-Cookie or CSP mutations. Requires application-layer telemetry.
03 · Intelligence Metadata

The supporting signals.

CVECVE-2026-1642 — nginx SSL Upstream Injection (race condition on upstream TLS)
In the wildNo known exploitation. Not on CISA KEV as of 2026-07-23. No public campaigns tracked.
Public PoCNo weaponized PoC published. Root-cause writeup in CVEReports analysis describes the READ-before-handshake race; reproduction requires a custom MITM harness.
EPSS0.00012 (~0.05 percentile) — statistically zero probability of exploitation in the next 30 days
CVSSv4.0 8.2 HIGH (F5) vs v3.1 5.9 MEDIUM — vector AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N. Integrity-only; MITM prerequisite is the hidden cost.
Affectednginx OSS and NGINX Plus, 1.3.0 → 1.29.4. Applies only when proxying to a TLS upstream (proxy_pass https://…, gRPC over TLS, uWSGI+SSL).
Fixed1.28.2 (stable) released 2026-02-04, 1.29.5 (mainline). Debian/Ubuntu/RHEL backports followed within 2 weeks.
Discovered byF5 internal research; disclosure coordinated by Jan Schaumann (netmeister.org) via oss-security 2026-02-04
ExposureShodan shows ~35M nginx instances on the internet, but the vulnerable path is *upstream-facing* — not directly probeable from the internet. Real exposed surface is far smaller.
CWECWE-349 — Acceptance of Extraneous Untrusted Data With Trusted Data
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.4/10)

Downgraded from HIGH to MEDIUM because the single decisive factor is the upstream-side MITM prerequisite: an attacker must already control the network segment between your nginx proxy and its backend, which sits inside the datacenter/VPC trust boundary. Any adversary with that position has strictly more impactful primitives available than injecting a response body, and the impact vector is integrity-only (VC:N/VI:H/VA:N).

HIGH Affected version ranges and fix availability
HIGH Absence of in-the-wild exploitation
MEDIUM Practical exploitability of the race window in production configs

Why this verdict

  • MITM position is the gate: the attacker must already sit between nginx and its upstream — a network position that, in modern datacenter and cloud fabrics, implies prior compromise of the east-west network. That single prerequisite cuts realistic exposure by orders of magnitude.
  • Integrity-only impact: the bug is VI:H with VC:N and VA:N. No code execution, no credential theft, no data exfiltration primitive. The worst case is cache poisoning or WAF bypass — recoverable and detectable.
  • Race window is narrow: exploitation requires winning a millisecond-scale race against the TLS Client Hello. TLS session resumption and any TLS-terminating middlebox in the upstream path shut the window entirely.
  • Role multiplier — reverse proxy fronting backend services: nginx here is a canonical high-value role (traffic edge), but the chain fails when the upstream leg is a service mesh, private link, or same-host loopback. Even in a plausible worst-case (poison the cache of a customer-facing tenant), blast radius is bounded to that tenant's cached responses, not fleet-wide.
  • No KEV, EPSS ~0.0001: F5 disclosed it responsibly, patch shipped same day, and six months later there is still no known weaponization.

Why not higher?

HIGH would require either a realistic remote-unauthenticated path (there is none — MITM on upstream is not that) or fleet-scale impact. Neither holds. The v4.0 8.2 score treats AT:P (attack requirements present) as a smaller discount than it deserves for this specific prerequisite class; v3.1's 5.9 MEDIUM is closer to operational reality.

Why not lower?

LOW would ignore that nginx is the most-deployed reverse proxy on earth and that shared-tenancy cloud, misconfigured service meshes, and flat east-west VLANs do exist. Where the MITM position is achievable, integrity compromise of the upstream response is a real cache-poisoning / WAF-bypass primitive. MEDIUM keeps it on the patch cycle without displacing genuinely urgent work.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade nginx to 1.28.2 or 1.29.5+ — This is the actual fix — schedule within the noisgate remediation SLA for MEDIUM (≤365 days), but prefer next standard maintenance window. Distro backports are shipped for Debian, Ubuntu, RHEL, Amazon Linux, Alpine.
  2. Verify upstream traffic runs over private link, VPC peering, or a service mesh with mTLS — Eliminates the MITM prerequisite entirely. If your proxy_pass https://… targets are on the same VPC or reached via PrivateLink / Cloud Interconnect / a mesh sidecar, the exploitable surface collapses to zero.
  3. Enable proxy_ssl_verify on with pinned upstream CA — Doesn't fix the race directly, but ensures the injected plaintext never gets promoted past the TLS layer on subsequent requests; also catches broader upstream tampering.
  4. Disable proxy_cache on sensitive endpoints — Removes persistence for any injected response, cutting cache-poisoning impact even if the race is won for a single request.
What doesn't work
  • WAF rules on the client-facing leg — the injection happens on the upstream leg, so a client-side WAF sees the poisoned response after nginx has already accepted it.
  • HSTS / client-side TLS pinning — these protect the browser↔nginx leg, not nginx↔upstream.
  • Rate limiting — the race is a single-shot injection, not a volumetric attack.
  • IP allowlisting the upstream — an attacker with MITM already sees traffic from the allowed IP; the allowlist doesn't stop injection.
06 · Verification

Crowdsourced verification payload.

Run on each host that runs nginx (as root or a user in the nginx group). Example: sudo bash check-nginx-1642.sh. Detects both OSS and NGINX Plus builds; parses nginx -v and compares to the fixed versions.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-nginx-1642.sh — detect CVE-2026-1642 exposure
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u

NGINX_BIN="$(command -v nginx || true)"
if [ -z "$NGINX_BIN" ]; then
  echo "UNKNOWN: nginx not found in PATH"
  exit 2
fi

VER_RAW="$($NGINX_BIN -v 2>&1)"
# e.g. "nginx version: nginx/1.24.0" or "nginx/1.29.5 (nginx-plus-r33)"
VER="$(echo "$VER_RAW" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
if [ -z "$VER" ]; then
  echo "UNKNOWN: could not parse version from: $VER_RAW"
  exit 2
fi

IFS=. read -r MAJ MIN PATCH <<<"$VER"

vuln=0
# Fixed: 1.28.2+ (stable) or 1.29.5+ (mainline). Anything else in 1.3.0..1.29.4 is vulnerable.
if [ "$MAJ" -eq 1 ]; then
  if [ "$MIN" -lt 3 ]; then
    vuln=0  # <1.3.0 not affected per advisory
  elif [ "$MIN" -lt 28 ]; then
    vuln=1
  elif [ "$MIN" -eq 28 ] && [ "$PATCH" -lt 2 ]; then
    vuln=1
  elif [ "$MIN" -eq 29 ] && [ "$PATCH" -lt 5 ]; then
    vuln=1
  fi
fi

# Check if proxy_pass https:// or grpcs:// is actually configured — the vuln path
CONF_DIR="/etc/nginx"
HAS_TLS_UPSTREAM=0
if [ -d "$CONF_DIR" ]; then
  if grep -REq 'proxy_pass[[:space:]]+https://|grpc_pass[[:space:]]+grpcs://|uwsgi_pass.*ssl' "$CONF_DIR" 2>/dev/null; then
    HAS_TLS_UPSTREAM=1
  fi
fi

if [ "$vuln" -eq 1 ]; then
  if [ "$HAS_TLS_UPSTREAM" -eq 1 ]; then
    echo "VULNERABLE: nginx $VER with TLS upstream configured (CVE-2026-1642)"
  else
    echo "VULNERABLE: nginx $VER (no TLS upstream currently configured — still upgrade)"
  fi
  exit 1
fi

echo "PATCHED: nginx $VER (>= 1.28.2 or >= 1.29.5)"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday: run the version check across your nginx fleet and tag any host running <1.28.2 stable / <1.29.5 mainline. This is MEDIUM — there is no noisgate mitigation SLA for this bucket, so go straight to the noisgate remediation SLA of ≤365 days and roll the patch into your next standard maintenance window (aim for the next 60–90 days if your change process allows). Priority-tier the hosts by whether proxy_pass https://… is actually configured *and* whether the upstream leg traverses shared infrastructure (multi-tenant cloud, cross-VPC, WAN) — those are the only realistic exposure surfaces. Deprioritize hosts where upstreams are same-VPC, mesh-terminated, or loopback. Do not page anyone; do not open a war room.

Sources

  1. Tenable Plugin 304671
  2. oss-security disclosure (Jan Schaumann)
  3. CVEReports technical analysis — race condition breakdown
  4. nginx security advisories
  5. Broadcom KB — CVE-2026-1642 impact assessment
  6. kubernetes/ingress-nginx tracking issue #14528
  7. docker-nginx-unprivileged release request
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.