DEV Community

Nathan Sportsman
Nathan Sportsman

Posted on

When Proxies Become the Attack Vectors in Web Architectures

Many modern web applications rely on a flawed assumption: backends can blindly trust security-critical headers from upstream reverse proxies. This assumption breaks down because HTTP RFC flexibility allows different servers to interpret the same header field in fundamentally different ways, creating exploitable gaps that attackers are increasingly targeting.

Two recent CVEs I discovered expose this systemic problem and demonstrate why these are not isolated bugs, but symptoms of a much broader architectural flaw. When CVE-2025-48865 in Fabio and CVE-2025-64484 in OAuth2-proxy both enable identical attack patterns across completely different technologies, it reveals that our industry has fundamentally misunderstood where the real security boundaries lie.

TL;DR: Two newly discovered CVEs (CVE-2025-48865 in Fabio, CVE-2025-64484 in OAuth2-proxy) expose a systemic vulnerability in how reverse proxies handle header processing. By exploiting hop-by-hop header stripping and underscore-hyphen normalization differences, attackers can bypass proxy security controls to achieve authentication bypass and privilege escalation. These are not isolated bugs. They are symptoms of a fundamental trust boundary problem in modern proxy-backend architectures.


Hop-by-Hop Header Abuse in Fabio (CVE-2025-48865)

In a typical setup, reverse proxies strip untrusted client headers and inject their own security-critical values (such as X-Forwarded-For and X-Real-IP), which backends then use for authentication and access control decisions.

However, HTTP's Connection header allows clients to designate certain headers as "hop-by-hop," meaning they should be processed only by the immediate recipient and stripped before forwarding. By setting something like:

Connection: close, X-Forwarded-Host
Enter fullscreen mode Exit fullscreen mode

an attacker can trick the proxy into removing security headers it would normally preserve and trust.

This attack method has surfaced across multiple reverse proxy implementations, including Apache HTTP Server (CVE-2022-31813) and Traefik (CVE-2024-45410). I discovered that Fabio was susceptible to the same abuse by including security-critical headers like Forwarded in the Connection header, causing Fabio to strip them before forwarding the request to the backend.

What is a hop-by-hop header attack?

HTTP's Connection header was designed to let clients specify which headers are "hop-by-hop": they should only be processed by the immediate recipient (the proxy) and removed before forwarding to the next server.

Attackers abuse this by listing security-critical headers like X-Forwarded-For or X-Real-IP in the Connection header, tricking the proxy into stripping headers that the backend relies on for authentication and access control.

Normal flow:

Client --> Proxy (preserves X-Forwarded-For) --> Backend (uses it for auth)
Enter fullscreen mode Exit fullscreen mode

Attack flow:

Client sends: Connection: close, X-Forwarded-For
Client --> Proxy (strips X-Forwarded-For!) --> Backend (auth logic never triggers)
Enter fullscreen mode Exit fullscreen mode

Why stripping these headers is dangerous

Headers like X-Real-IP and X-Forwarded-For often drive access control decisions, determining whether a request is internal or external, or whether a sensitive endpoint should be accessible.

For example, ProjectDiscovery's research into Versa Concerto found that the application relied on X-Real-IP to restrict access to Spring Boot Actuator endpoints. If that header gets stripped, the security logic simply never triggers.


The Underscore-Hyphen Normalization Problem

Header normalization creates yet another attack vector that exploits the same fundamental trust boundary weakness. Many web application frameworks automatically normalize header names during processing:

Framework Behavior Example
Capitalize + standardize separators client-verified becomes Client-Verified
Case normalization x-real-ip treated same as X-Real-IP
Underscore-to-hyphen conversion x_forwarded_email becomes X-Forwarded-Email

These normalization differences create systematic opportunities for attackers to smuggle headers using variations that proxy servers don't recognize, but backends will normalize and process as trusted security headers.

Deutsche Telekom Security's research specifically highlighted this underscore-hyphen normalization problem. Different frameworks handle it inconsistently: some convert hyphens to underscores, while others make headers accessible regardless of the original separator format.


OAuth2-Proxy Authentication Bypass via Underscore Smuggling (CVE-2025-64484)

OAuth2-proxy is an authentication proxy that sits between users and backend applications, handling OAuth2/OIDC authentication flows for applications that don't natively support them. When a user authenticates, OAuth2-proxy forwards the request to the backend along with user information in headers like X-Forwarded-User and X-Forwarded-Email.

Here's the problem: OAuth2-proxy correctly strips X-Forwarded-Email from incoming client requests, but it only filters the standard hyphenated version. Underscore variants like X_Forwarded_Email pass through unfiltered.

When these underscore-based headers reach backend applications that normalize header names (converting them back to the hyphenated form), the backend treats them as trusted authentication headers.

The attack in practice:

# Attacker sends:
GET /admin HTTP/1.1
Host: target.com
X_Forwarded_Email: admin@target.com

# OAuth2-proxy sees X_Forwarded_Email (underscores)
#   --> not in its filter list, passes through

# Backend framework normalizes X_Forwarded_Email to X-Forwarded-Email
#   --> treats it as trusted auth header
#   --> attacker is now authenticated as admin@target.com
Enter fullscreen mode Exit fullscreen mode

The result: an attacker can impersonate any user, including administrators, leading to privilege escalation or full account takeover.


MITRE ATT&CK TTP Mapping

These header injection techniques map to several MITRE ATT&CK tactics:

Tactic Technique How It Applies
Initial Access T1190 - Exploit Public-Facing Application Targeting proxy configurations to bypass auth
Defense Evasion T1562 - Impair Defenses Circumventing proxy security filters via normalization abuse
Privilege Escalation T1068 Injecting auth headers to impersonate legitimate users
Lateral Movement -- Compromised auth may grant access to additional internal systems

Defending Against Proxy Trust Boundary Attacks

Defending against these vulnerabilities requires precise adherence to the HTTP RFC and careful handling of ambiguous behaviors like header normalization and case sensitivity. Organizations must evaluate how different HTTP servers and frameworks interact before deployment, as these implementation differences create the attack surface.

Key defensive measures:

  1. Sanitize all header variants at the proxy layer. Block underscore variants, case variations, and any other formats that could be normalized by backend frameworks.

  2. Allowlist legitimate hop-by-hop headers. Do not let arbitrary headers be designated as hop-by-hop through the Connection header.

  3. Implement backend-side verification. Consider cryptographic signing of authentication headers so backends can validate their authenticity regardless of proxy behavior. (Rarely implemented in practice, but the strongest mitigation.)

  4. Audit your specific proxy-backend combination. The attack depends on parsing mismatches between your proxy and backend framework. Test your actual stack for these gaps.

  5. Keep proxy software patched. Both CVEs discussed here have patches available.

Most importantly, backends should validate rather than blindly trust security-critical headers from proxies. The fundamental lesson from both of these CVEs is the same: when the trust boundary between your proxy and backend is implicit rather than cryptographically enforced, every normalization difference and every protocol ambiguity becomes an attack surface.


References

Top comments (0)