Bug 59456

Summary: Headers set with RequestHeader containing underscores in the name can be spoofed by clients
Product: Apache httpd-2 Reporter: ScottE <lscotte>
Component: mod_headersAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: CLOSED INVALID    
Severity: normal    
Priority: P2    
Version: 2.4.7   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description ScottE 2016-05-11 00:29:11 UTC
This might be best handled by an update to the documentation, but I discovered that one must be careful when using RequestHeaders and using header names containing underscores (which get converted to dashes), as they can be spoofed. This is especially important if validating security information, for example with variables provided by mod_ssl.

For example, the following header can be spoofed (overridden) by a client:

RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"  # Don't do this!

However these cannot:

RequestHeader set SSL-CLIENT-VERIFY "%{SSL_CLIENT_VERIFY}s"  # Do this
RequestHeader set Ssl-Client-Verify "%{SSL_CLIENT_VERIFY}s"  # Do this

Although in all cases the resulting header will be "Ssl-Client-Verify", a client can actually spoof the first form by providing a forged header exactly matching the final header name.

Again, this is arguably not a bug, however it can result in unexpected behavior when people lazily create configurations with underscores (and unfortunately there are plenty of bad "guides" with this sort of example configuration). It would be worth clarifying this in the documentation, as the behavior is not obvious.

This is on 2.4.7, but I didn't find anything suggesting this behavior changed in more recent versions.
Comment 1 ScottE 2016-07-28 20:12:25 UTC
I'm a bit surprised that nobody has jumped on this as it's NOT an Apache issue. I did not do my due diligence on this, and it turns out to entirely be a problem in the request processing framework of the application Apache is proxying requests to. It turns out that some frameworks follow old CGI specs that prohibit hyphens ("-") in request header names. Apache is passing along both it's header and the client-generated headers, but the proxied framework converts "-" to "_" which results in a map/dictionary key collision.

The net results of this is my "Do this" advise is wrong and better advice (if you have no control over what the request processing code does) is use constructs like:

RequestHeader set SSLCLIENTVERIFY "%{SSL_CLIENT_VERIFY}s"  # Do this

I.e. mitigate the issue completely by avoiding "-" and "_" entirely.
Comment 2 ScottE 2016-07-28 20:12:52 UTC
Closing as RESOLVED/INVALID.