Apr 16, 2026·6 min read·2 visits
A vulnerability in Fastify proxy plugins allows clients to strip proxy-injected security headers by exploiting the RFC 7230 hop-by-hop stripping mechanism, leading to authentication bypasses and header spoofing.
A logic flaw in the header processing pipeline of @fastify/reply-from and @fastify/http-proxy allows unauthenticated remote attackers to bypass access controls or subvert routing. By manipulating the HTTP Connection header, clients can force the proxy to remove security-critical headers injected by the developer via the rewriteRequestHeaders hook.
The @fastify/reply-from and @fastify/http-proxy libraries facilitate reverse proxying and request forwarding in Node.js applications. These plugins allow developers to define custom hooks, such as rewriteRequestHeaders, to append authentication metadata, routing tokens, or identification headers before transmitting the request to an upstream server. This process is standard in microservice architectures where edge proxies handle initial client validation and context propagation.
CVE-2026-33805 identifies a logic flaw in how these plugins sequence HTTP header processing alongside the transport layer mechanism. The vulnerability allows unauthenticated remote attackers to circumvent developer-defined header injections. By exploiting the RFC 7230 specification regarding hop-by-hop headers, an attacker can coerce the proxy into discarding its own security metadata before the request reaches the destination.
The core weakness is categorized as CWE-644: Improper Neutralization of HTTP Headers for Scripting Syntax. The Common Vulnerability Scoring System evaluates this flaw at 9.0 due to the high integrity impact on downstream services. The vulnerability exposes any upstream service relying on proxy-injected headers to access control bypasses or origin spoofing.
The vulnerability stems from an incorrect order of operations within the request lifecycle of the proxy pipeline. Under normal operations, the proxy collects all headers from the incoming client request and passes them to the rewriteRequestHeaders hook. The developer uses this hook to inject trusted metadata, combining the client headers with the new proxy-generated headers.
Following the injection phase, the combined set of headers is passed to the transport handler, which relies on either Undici or the native Node.js http module. Under RFC 7230, the Connection header specifies hop-by-hop headers that a proxy must remove before forwarding the message. The transport handler implements this specification by reading the Connection header and iteratively deleting any header key listed within it.
Because the header stripping logic occurs entirely after the developer injection logic, the transport layer cannot distinguish between headers originally sent by the client and those explicitly added by the proxy. A malicious client can pre-emptively supply a Connection header containing the exact keys the proxy intends to add. When the transport layer processes the hop-by-hop instructions, it retroactively strips the newly injected security headers from the outgoing request object.
The vulnerable code path resides within lib/request.js for both HTTP/1.1 and Undici handlers. In the unpatched versions, the application processes the Connection header immediately before handing the request off to the outbound connection socket. This late-stage evaluation meant all modifications made during the routing phase were vulnerable to deletion.
The patch resolves the issue by repositioning the hop-by-hop stripping mechanism to the earliest stage of the proxy pipeline. The system now parses the client-supplied Connection header and deletes the specified tokens immediately after cloning the initial headers, strictly before rewriteRequestHeaders is invoked.
@@ -89,6 +90,18 @@
const sourceHttp2 = req.httpVersionMajor === 2
const headers = sourceHttp2 ? filterPseudoHeaders(req.headers) : { ...req.headers }
+
+ // Strip client-supplied Connection header and tokens before rewriteRequestHeaders runs.
+ const connectionHeaderNames = getConnectionHeaders(headers)
+ if (headers.connection || connectionHeaderNames.length > 0) {
+ delete headers.connection
+ for (let i = 0; i < connectionHeaderNames.length; i++) {
+ delete headers[connectionHeaderNames[i]]
+ }
+ }This structural change ensures that client-controlled connection directives only apply to the payload the client submitted. Any headers injected subsequently by the developer exist in an isolated state and pass unaltered to the upstream transport handler.
Exploiting CVE-2026-33805 requires no authentication, specific configurations, or complex timing. The attacker only needs the ability to route an HTTP request through the vulnerable proxy and prior knowledge (or a valid assumption) of the specific header names the proxy uses to communicate with upstream services.
The attack vector involves injecting the targeted header name as a comma-separated value within the standard Connection header. The following proof-of-concept demonstrates this mechanism against a proxy configured to append an x-forwarded-by header:
// Attack: Connection header strips the proxy-added header
const res2 = await proxy.inject({
method: 'GET',
url: '/proxy/api/echo-headers',
headers: { 'connection': 'x-forwarded-by' }
});When the vulnerable proxy processes this request, it first adds x-forwarded-by: fastify-proxy to the header object. In the final preparation stage, the transport layer parses the Connection: x-forwarded-by string and executes a delete operation on the x-forwarded-by key. The upstream service receives the request devoid of the required identification context.
The security impact of CVE-2026-33805 scales directly with the upstream service's reliance on proxy-injected headers. The most severe consequence is access control bypass. If the proxy injects headers such as X-Internal-Secret or X-User-Role to signify that a request successfully passed gateway authentication, stripping these headers removes the authorization context entirely. Depending on upstream fallback logic, this may lead to default-allow conditions or unauthenticated data exposure.
The vulnerability also facilitates robust identification spoofing. Edge proxies routinely append X-Forwarded-For or X-Real-IP to track the true origin of a request. By stripping these tracking mechanisms, attackers can obscure their source IP addresses, thwarting rate-limiting mechanisms and incident response tracking. Furthermore, this technique can subvert internal service mesh routing that depends on specific header presence for load balancing or tenant isolation.
The CVSS v4.0 vector CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:L/SI:H/SA:N reflects the low complexity and network-based nature of the attack. The high integrity scores denote the proxy's inability to maintain the fidelity of the request data passing through its pipeline.
The primary and most effective remediation is upgrading the affected dependencies to their patched versions. Organizations must update @fastify/reply-from to version 12.6.2 or later, and @fastify/http-proxy to version 11.4.4 or later. These upgrades contain the architectural change necessary to evaluate the Connection header safely before applying proxy augmentations.
For environments where immediate patching is not feasible, security teams can deploy Web Application Firewall (WAF) rules to detect and block malicious Connection headers. The WAF should inspect the Connection header values and drop requests containing sensitive internal header names, such as x-forwarded-for, x-internal-auth, or authorization.
Developers should also review upstream services to ensure they implement robust default-deny behaviors. Upstream applications must explicitly reject requests that lack expected authentication or routing headers, rather than degrading gracefully or applying generic guest privileges when context headers are missing.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:L/SI:H/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@fastify/reply-from Fastify | <= 12.6.1 | 12.6.2 |
@fastify/http-proxy Fastify | <= 11.4.3 | 11.4.4 |
| Attribute | Detail |
|---|---|
| CVSS Score | 9.0 (Critical) |
| Attack Vector | Network |
| CWE ID | CWE-644 |
| Exploit Status | PoC Available |
| EPSS Score | 0.00042 (12.75%) |
| Authentication | None Required |
Improper Neutralization of HTTP Headers for Scripting Syntax