A single HTTP header with an underscore instead of a hyphen bypassed authentication for an entire OAuth2-proxy deployment. No brute force. No stolen credentials. Just X_Forwarded_User instead of X-Forwarded-User.
This is CVE-2025-64484, and it's a clear example of how proxy-backend parsing differences create exploitable gaps in your security perimeter.
What Happened
Two critical vulnerabilities emerged in widely-deployed reverse proxy configurations:
CVE-2025-48865 (Fabio): Attackers exploited the HTTP Connection header to force Fabio to strip security-critical headers before forwarding requests to backend applications. By manipulating which headers Fabio considered "connection-specific," attackers could remove authentication headers that backends relied on for access control decisions.
CVE-2025-64484 (OAuth2-proxy): OAuth2-proxy failed to sanitize underscore variants of forwarded headers. While the proxy correctly processed X-Forwarded-User, it ignored X_Forwarded_User. Backend applications that normalized underscores to hyphens accepted the attacker-controlled header as legitimate, granting unauthorized access.
Both vulnerabilities share a root cause: proxies and backends parsed HTTP headers differently, and neither component validated that the other had processed headers correctly.
Timeline
The attack sequence for CVE-2025-64484 follows this pattern:
- Initial request: Attacker sends request with both
X-Forwarded-User: [email protected](legitimate) andX_Forwarded_User: [email protected](malicious). - Proxy processing: OAuth2-proxy validates authentication, sets
X-Forwarded-Usercorrectly, but doesn't stripX_Forwarded_User. - Backend processing: Application normalizes header names, converting underscores to hyphens.
- Header collision: Backend now sees two
X-Forwarded-Userheaders and processes the attacker's value. - Access granted: Application authorizes request as
[email protected]despite failed OAuth2 validation.
CVE-2025-48865 follows similar logic but uses the Connection header to manipulate which headers reach the backend at all.
Which Controls Failed
Input validation at trust boundaries: Both proxies failed to enforce strict header allowlists. OAuth2-proxy should have stripped all X_Forwarded_* variants before setting its own. Fabio should have rejected Connection header values that referenced security-critical headers.
Defense in depth: Backend applications trusted proxy-set headers without independent verification. No secondary validation. No signature verification. No mutual TLS with header binding.
Configuration validation: Neither deployment included automated checks for dangerous proxy-backend combinations. No testing for header normalization differences. No validation that security-critical headers couldn't be overridden.
Change management: Updates to proxy configurations or backend header-parsing libraries happened independently, without security review of the combined behavior.
What Standards Require
OWASP ASVS v4.0.3 Requirement 5.2.1: "Verify that the application server only accepts the HTTP methods in use by the application/API, including pre-flight OPTIONS, and logs/alerts on any requests that are not valid for the application context."
This extends to header validation. Your proxy must reject or strip headers that could conflict with its own security decisions.
PCI DSS v4.0.1 Requirement 6.4.2: "For public-facing web applications, an automated technical solution is deployed that continually detects and prevents web-based attacks."
Your WAF or proxy must understand the full request path. If your backend normalizes underscores to hyphens, your proxy's sanitization logic must account for this.
NIST 800-53 Rev 5 Control SI-10: "Information Input Validation - Check the validity of information inputs."
This applies at every trust boundary. Your proxy is a trust boundary. Your backend is a trust boundary. Each must validate independently that the other hasn't been compromised or misconfigured.
ISO 27001 Annex A.8.3: "Information security for use of networks - Networks and network services shall be secured and protected."
Your proxy-backend architecture is a network service. Document the security assumptions each component makes about the other. Test those assumptions.
Lessons and Action Items
Audit your header flow today:
Map every header your proxy sets and every header your backend consumes. For each security-critical header (authentication, authorization, origin), document:
- Exact header name the proxy sets
- Whether the proxy strips attacker-controlled variants
- How the backend parses header names (case-sensitive? underscore normalization?)
- What happens if multiple headers with the same normalized name exist
Implement strict header allowlists:
Configure your proxy to strip ALL incoming headers that match patterns it uses for security decisions. For OAuth2-proxy deployments, block any incoming header matching X-Forwarded-*, X_Forwarded_*, X-FORWARDED-* before authentication. Set your own headers after validation.
Test for parsing differences:
Send test requests with header variants through your full proxy-backend chain:
X-Custom-Header: value1
X_Custom_Header: value2
X-CUSTOM-HEADER: value3
Log which values your backend receives and in what order. If you see unexpected behavior, you have a smuggling risk.
Add backend validation:
Don't trust proxy-set headers blindly. Options:
- Require mutual TLS between proxy and backend, bind headers to client certificates
- Implement header signatures using shared secrets
- Validate that security-critical headers match expected formats and values
- Log and alert when headers appear to be manipulated
Review Connection header handling:
If your proxy honors Connection header directives, restrict which headers can be listed. Never allow Connection to reference authentication, authorization, or origin headers. Better: ignore Connection header entirely for security-critical headers.
Update your threat model:
Add "proxy-backend parsing differences" as an explicit threat. Include it in security reviews when:
- Updating proxy software
- Changing backend frameworks
- Modifying header-based authentication
- Adding new reverse proxy layers
The OAuth2-proxy and Fabio vulnerabilities weren't edge cases. They're examples of a systemic problem: we build security architectures from components that make different assumptions about HTTP parsing. Until you verify those assumptions match, your authentication layer is one header variant away from complete bypass.



