During a web application test I encountered an interesting mismatch between a WAF and the backend application. The WAF blocked requests that contained a specific authentication header. Internally, the rule was implemented as a simple string check against the first occurrence of X-Custom-Auth.
HTTP headers are not guaranteed to appear only once. Many servers and frameworks allow duplicate headers and then apply their own logic to decide which value should be used. Some concatenate them, others keep the first value, and some prefer the last.
In this case the WAF inspected only the first header instance while the backend framework used the last value. That difference created a gap between what the WAF believed the request looked like and how the application actually interpreted it.
To test the behavior I sent two headers:
X-Custom-Auth: test | X-Custom-Auth: real-auth-token
The WAF inspected the first value, saw the benign string, and allowed the request to continue. The application server then processed the request and used the second header value as the effective authentication token.
This is not a novel technique, but it is a good reminder that security controls often depend on consistent parsing across multiple layers. When those layers interpret the same request differently, bypasses become possible.
I am intentionally not naming the product involved because the underlying issue is generic and has appeared in different implementations over time.
The defensive lesson is straightforward:
- Normalize headers before performing inspection.
- Define clear behavior for duplicate headers.
- Ensure that security layers and application frameworks interpret requests in the same way.
Assuming that a header appears only once is convenient but unsafe. HTTP allows duplicates, and attackers will inevitably test that boundary.