CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-1642

NGINX Upstream TLS Injection: Racing the Handshake

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 6, 2026·5 min read·909 visits

Executive Summary (TL;DR)

NGINX checks for incoming data (Read Event) before sending the TLS Client Hello (Write Event) on new upstream connections. Attackers can race this logic by sending plain text HTTP immediately upon TCP connect. NGINX accepts the unencrypted data, skipping TLS negotiation.

A high-severity race condition in NGINX's event loop allows a Man-in-the-Middle attacker to bypass upstream TLS protections entirely. By injecting a plain text HTTP response immediately after TCP connection establishment—but before the TLS handshake begins—an attacker can trick NGINX into processing and serving the malicious payload as if it came from the trusted backend.

The Hook: The Illusion of Security

We trust NGINX to be the bouncer. You configure proxy_pass https://backend.internal and you sleep soundly, assuming that the connection between your proxy and your backend is wrapped in a cozy blanket of TLS encryption. If a hacker is sitting on the wire, they should see nothing but garbage, right?

Wrong. Security is often an illusion held together by the sequence of events. If you change the sequence, the security evaporates. CVE-2026-1642 is a classic "Time-of-Check to Time-of-Use" (TOCTOU) sibling, born from the complexities of asynchronous, event-driven architecture.

Here is the punchline: You can tell NGINX to use HTTPS, but if the server (or an imposter) screams "HTTP 200 OK" fast enough, NGINX forgets it was supposed to negotiate encryption and just takes the data. It's like walking into a bank vault, but the guard is so distracted by someone handing him a donut that he forgets to ask for your ID.

The Flaw: Read vs. Write

To understand this bug, you have to think like an event loop. NGINX is non-blocking. When it initiates a connection to an upstream server, it registers interest in two things: writing data (to start the handshake) and reading data (the response).

Ideally, the flow is:

  1. TCP Connect.
  2. Write Event: NGINX sends Client Hello.
  3. Read Event: NGINX receives Server Hello.

But the internet is messy. If a TCP connection is established and data arrives immediately, the event loop might fire both the READ and WRITE events in the same cycle. NGINX, in its infinite efficiency, processes the READ event first.

The function ngx_http_upstream_process_header gets called. It looks at the buffer. It sees valid HTTP headers. It parses them. It prepares the response for the client. Crucially, it never checks if the SSL handshake it intended to perform actually happened. It just assumes that if it's reading data, everything must be fine.

The Code: The Smoking Gun

The fix, authored by Roman Arutyunyan at F5, is embarrassingly simple, which highlights just how subtle this logic flaw was. The vulnerability lived in src/http/ngx_http_upstream.c.

The patch introduces a sanity check. Before processing any header data, NGINX now asks: "Am I configured to use SSL (u->ssl)? And if so, is the SSL context (c->ssl) currently NULL?"

Here is the fix in all its glory:

// src/http/ngx_http_upstream.c
 
@@ -2508,6 +2508,15 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
             return;
         }
 
+#if (NGX_HTTP_SSL)
+        // THE FIX: Check if we expect SSL but haven't started it yet
+        if (u->ssl && c->ssl == NULL) {
+            ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                          "upstream prematurely sent response");
+            ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
+            return;
+        }
+#endif
+
         u->state->bytes_received += n;

Without this block, the code would happily fall through to u->buffer.last += n and begin parsing the attacker's plain text injection as a legitimate response.

The Exploit: Beating the Clock

Exploiting this requires a Man-in-the-Middle (MITM) position between NGINX and the upstream server. This sounds hard, but in modern microservices environments (Kubernetes, internal clouds), ARP spoofing or compromised routers are fair game.

The attack chain looks like this:

  1. Intercept: The attacker sees NGINX initiate a TCP handshake (SYN) to the targeted upstream.
  2. Connect: The attacker (or the compromised upstream) completes the TCP handshake (SYN-ACK).
  3. Race: BEFORE NGINX can execute its write handler to send the TLS Client Hello, the attacker floods the socket with a plain text HTTP response.
    HTTP/1.1 200 OK
    Content-Type: application/json
     
    {"status": "admin_access_granted"}
  4. Win: NGINX sees the data. The Read Event handler fires. It parses the JSON. It serves it to the user.

The Client Hello might eventually be sent, or the connection might error out afterwards, but it's too late. The response has been accepted. If NGINX is configured to cache responses, the attacker has now poisoned the cache for everyone.

The Impact: Trust Issues

Why is this rated High (CVSS 8.2) despite requiring MITM? Because it breaks the fundamental promise of proxy_pass https://. Architects design systems assuming that if they enforce TLS, they are safe from injection attacks on the wire.

This vulnerability allows for:

  • Cache Poisoning: Injecting malicious JavaScript or fake data that gets cached and served to legitimate users.
  • WAF Bypass: If a WAF sits before NGINX, but NGINX trusts the upstream, injecting data here bypasses ingress protections.
  • Integrity Violation: Total control over the response content.

It is worth noting that this does not break the confidentiality of the request (the attacker can't necessarily decrypt what NGINX sends to the upstream), but they can completely fabricate the response.

The Fix: Patch Tuesday

If you are running NGINX Open Source versions 1.3.0 through 1.29.4, you are vulnerable. If you are on NGINX Plus R36 or earlier, you are likely vulnerable too.

Remediation:

  1. Patch: Upgrade to NGINX 1.29.5, 1.28.2, or NGINX Plus R36 P2 immediately.
  2. Monitor: Keep an eye on your error logs. The patch introduces a specific error message: upstream prematurely sent response. If you see this, someone (or something) is trying to race your TLS handshake.
  3. Architecture: Zero Trust isn't just a buzzword. Authenticated mTLS (mutual TLS) can make the initial TCP/TLS negotiation harder to spoof, though this specific race condition ignores the handshake entirely, so patching is the only true fix.

Official Patches

F5 / NGINXOfficial patch in NGINX source tree
F5 Security AdvisoryAdvisory K000159824

Fix Analysis (1)

Technical Appendix

CVSS Score
8.2/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
EPSS Probability
0.01%
Top 99% most exploited

Affected Systems

NGINX Open SourceNGINX PlusKubernetes Ingress Controllers (using affected NGINX versions)Load Balancers based on NGINX

Affected Versions Detail

Product
Affected Versions
Fixed Version
NGINX Open Source
F5
1.3.0 - 1.29.41.29.5
NGINX Plus
F5
R36 < P2R36 P2
AttributeDetail
CWECWE-349
CVSS v4.08.2 (High)
CVSS v3.15.9 (Medium)
Attack VectorNetwork (MITM)
ImpactIntegrity (High)
EPSS Score0.00012 (~1.44%)
Patch Commit376c3739b633e4ddac8ecf59d72e43b0b9151c51

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access / Collection
T1565Data Manipulation
Impact
CWE-349
Acceptance of Extraneous Untrusted Data With Trusted Data

The product accepts untrusted data that is extraneous to the expected data, which can lead to modification of the interpretation of the trusted data.

Known Exploits & Detection

HypotheticalAnalysis of the patch indicates trivial exploitation for any MITM capable of TCP stream manipulation.

Vulnerability Timeline

Fix committed to NGINX source
2026-01-29
Vulnerability Published
2026-02-04
Public Disclosure on oss-security
2026-02-05

References & Sources

  • [1]OSS-Security List Announcement
  • [2]CVE Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 days ago•CVE-2026-115895
8.8

CVE-2026-115895: Code Injection via Unsanitized Import Alias in Happy DOM ECMAScript Module Compiler

CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.

Amit Schendel
Amit Schendel
8 views•10 min read
•2 days ago•CVE-2026-115883
6.0

CVE-2026-115883: Cross-Namespace Access via Dot-Delimited Labels in LangGraph Postgres and SQLite Stores

An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.

Amit Schendel
Amit Schendel
8 views•9 min read
•2 days ago•CVE-2026-115886
6.5

CVE-2026-115886: Unauthenticated Server-Side Request Forgery and Unsafe Reflection in MLflow Scorer Evaluation Endpoints

CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.

Alon Barad
Alon Barad
12 views•10 min read
•2 days ago•CVE-2026-113872
7.5

CVE-2026-113872: Unauthenticated Process Crash in Express Multer via Late Busboy Stream Resumption

CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.

Amit Schendel
Amit Schendel
10 views•12 min read
•2 days ago•CVE-2026-115897
2.1

CVE-2026-115897: Cross-Site Scripting via Function Body Boundary Bypass in serialize-javascript

CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.

Amit Schendel
Amit Schendel
7 views•13 min read
•2 days ago•CVE-2026-109841
5.9

CVE-2026-109841: Subresource Integrity Verification Bypass in Node.js Undici

CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.

Alon Barad
Alon Barad
17 views•9 min read