Sep 11, 2026·6 min read·31 visits
Unauthenticated remote attackers can bypass Traefik security middlewares by upgrading a connection to cleartext HTTP/2 (h2c) over an unrestricted route, establishing a raw TCP tunnel directly to the backend that allows uninspected multiplexed streams to reach private paths.
An architectural flaw in the Traefik reverse proxy allows unauthenticated remote attackers to bypass security middlewares (such as basic authentication, IP allowlists, and forward authorization) by initiating an unencrypted HTTP/2 (h2c) upgrade request, causing the proxy to transition the connection into an opaque bi-directional TCP tunnel.
CVE-2026-88008 represents an architectural security flaw within Traefik, an industry-standard cloud-native HTTP reverse proxy and load balancer. The vulnerability centers on the handling of unencrypted HTTP/2 connection upgrades, commonly known as h2c. When configured to route traffic to backends that support these cleartext upgrades, Traefik exposes an attack surface that allows unauthenticated network clients to establish an unmonitored communication path.
The core of the exposure resides in how Traefik manages connection-state transitions. When a client requests a protocol transition over an unrestricted endpoint, the proxy permits the negotiation to pass down to the service layer. This behavior ultimately shifts the proxy out of its role as an application-layer policy enforcement point, converting the session into a transport-layer pipe.
The operational impact of this behavior is authorization bypass. Attackers exploit this behavior to transmit subsequent HTTP payloads directly to restricted backend routes, bypassing critical gateway security policies such as BasicAuth, ForwardAuth, IPAllowList, and rate limits. Because the proxy is blind to the encapsulated traffic, the downstream application processes unauthorized administrative operations as authenticated commands.
The underlying security flaw stems from an inconsistency in protocol interpretation between the edge proxy and the backend application server. According to the HTTP/2 specification (RFC 7540, Section 3.2), cleartext connection upgrades require a specific negotiation handshake. A client issues an HTTP/1.1 request containing Upgrade: h2c, a Connection: Upgrade, HTTP2-Settings header, and a base64-encoded HTTP2-Settings payload.
In Go-based applications utilizing the standard library's net/http/httputil package, the ReverseProxy implementation acts as a hop-by-hop forwarder. Historically, this component forwarded the upgrade headers directly to the backend destination instead of terminating or properly validating them. When the backend service accepts the transition, it issues an HTTP 101 Switching Protocols response.
Upon detecting the 101 status code, the standard library ReverseProxy transitions the network connection from structured HTTP request parsing into an opaque, bi-directional TCP tunnel. From this point forward, the proxy ceases all application-layer inspection of the data stream. It assumes the negotiation established a dedicated channel and simply copies raw bytes back and forth between client and server, failing to apply any route parsing, middleware analysis, or path-based access control filters.
To address this vulnerability, the Traefik development team introduced a dedicated middleware component named h2cUpgradeHandler within the proxy service chain. This handler intercepts all incoming HTTP/1.1 requests prior to forwarding them to the reverse proxy engine, inspecting and neutralizing the hazardous connection headers.
The logic within pkg/server/service/upgrade.go relies on the golang.org/x/net/http/httpguts utility library to inspect connection tokens safely. Below is the implemented fix:
package service
import (
"net/http"
"golang.org/x/net/http/httpguts"
)
// h2cUpgradeHandler removes a client-initiated h2c upgrade before the request reaches the reverse proxy.
// This is a temporary workaround for httputil.ReverseProxy, which forwards the token.
type h2cUpgradeHandler struct {
next http.Handler
}
func newH2CUpgradeHandler(next http.Handler) http.Handler {
return &h2cUpgradeHandler{next: next}
}
func (h *h2cUpgradeHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") &&
httpguts.HeaderValuesContainsToken([]string{req.Header.Get("Upgrade")}, "h2c") {
// Stripping the Upgrade header prevents the reverse proxy from entering a TCP tunnel state
delete(req.Header, "Upgrade")
}
// HTTP2-Settings header is also connection-specific and must not be forwarded
delete(req.Header, "Http2-Settings")
h.next.ServeHTTP(rw, req)
}By deleting the Upgrade header during the evaluation phase, the reverse proxy engine no longer computes an upgrade type. Consequently, the proxy strips the Connection header and routes the message as a standard HTTP/1.1 transaction. The backend never receives the upgrade trigger, preventing connection hijacking and establishing complete policy enforcement over the request life cycle.
Exploiting CVE-2026-88008 requires three distinct phases: locating an unrestricted path, sending the upgrade payload, and transmitting multiplexed HTTP/2 frames. The attack requires no authentication credentials and can be executed remotely if the backend supports cleartext HTTP/2 transitions.
First, the attacker identifies a public endpoint (e.g., /public/assets/logo.png) that is not protected by middleware filters like BasicAuth or IPAllowList. The attacker sends a crafted HTTP/1.1 request targeting this route, embedding the h2c upgrade headers. This request transits through Traefik, which validates the path as public, processes no blocking middleware, and forwards the packet directly to the backend.
GET /public/assets/logo.png HTTP/1.1
Host: target.local
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAMAAABkAAQAAP__If the backend accepts the upgrade, it responds with status 101 Switching Protocols. Traefik routes this response back to the client and immediately transitions the connection into a raw TCP tunnel. The attacker now switches their client socket to speak HTTP/2, sending multiplexed frames targeting protected paths like /admin/settings or /api/keys. Because Traefik only monitors the connection at the transport layer, the backend processes these multiplexed requests without Traefik's security layers intercepting them.
The interaction flow between the unauthenticated attacker, the Traefik proxy instance, and the backend application highlights how the security context changes after the HTTP 101 state transition.
This architecture shows how subsequent requests bypass security boundaries. Once the connection shifts state, authorization decisions previously enforced at the perimeter are completely negated.
The primary remediation strategy is to upgrade Traefik instances to patch versions 2.11.57 or 3.7.13. These versions natively incorporate the h2cUpgradeHandler to dismantle upgrade requests at the proxy entry point, preventing the establishment of the unauthenticated TCP tunnel.
For environments where immediate platform upgrades are not feasible, network administrators must deploy backend-level configuration modifications. Disabling cleartext HTTP/2 (h2c) support on backend application servers effectively neutralizes the attack surface. If the backend refuses to transition protocol states, it returns a standard HTTP/1.1 response status, maintaining normal proxy inspection.
Additionally, if cleartext HTTP/2 communication between Traefik and its backend service layers is necessary, administrators should use HTTP/2 with prior knowledge. By modifying the backend server scheme definition to h2c:// in Traefik's dynamic configuration, the system initiates HTTP/2 traffic directly. This avoids the HTTP/1.1 upgrade sequence entirely, ensuring the proxy remains in control of stream allocation and routing security.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Traefik Traefik | >= 2.11.26, < 2.11.57 | 2.11.57 |
Traefik Traefik | >= 3.4.2, < 3.7.13 | 3.7.13 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-444 / CWE-863 |
| Attack Vector | Network (N) |
| CVSS v4.0 Score | 7.0 (High) |
| EPSS Score | 0.00 (Pending) |
| Impact | Authentication & Middleware Policy Bypass |
| Exploit Status | Proof-of-Concept State |
| CISA KEV Status | Not Listed |
The proxy and the backend interpret the sequence of stream/protocol state transitions differently, allowing downstream multiplexed traffic to bypass proxy-level controls.
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.
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.
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.
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.
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.
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.