Bug 61706

Summary: ProxyBadHeader Ignore does not ignore headers that fail check_header()
Product: Apache httpd-2 Reporter: Scott Shambarger <scott-apache>
Component: mod_proxy_httpAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: NEW ---    
Severity: normal    
Priority: P2    
Version: 2.4.28   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Scott Shambarger 2017-10-31 19:59:46 UTC
I have a reverse proxy to my cable modem.  The modem returns an invalid header field "Cache-Control : no-cache".  So, to work around the problem, I enabled ProxyBadHeader Ignore in my configuration.

However, apache returns the same 500 Internal Server Error I receive when ProxyBadHeader is the default IsError (and not even the 502 Bad Gateway documented for that setting)

Tracking the issue through the source, the problem appears that ap_proxy_read_headers() only applies ProxyBadHeader if the header is missing a ":".  When the proxied header is passed as a response to the request, http_filters.c:check_header() fails for the header, and the connection is aborted with 500.

The solution is that the same key/value checks that check_header() performs should be done in ap_proxy_read_headers() before the header is considered valid and added to r->headers_out (and could provide better trace logging when a bad header is encountered there).

NOTE: Ideally, there should be a new value for ProxyBadHeader which would allow a distinction between "ignore and discard" and "ignore and pass through" (so bad headers could be filtered)

To summarize:
* IsError should return 502 on any header that fails check_header()
* Ignore should probably discard bad headers as documented (better name would be "Discard" :).
* StartBody should start body based on the same check_header() check..

...and I would suggest a new value:
* Pass which should actually allow the header to be filtered (so the original values might be fixed and retained, but only if configured to do so!).

I could provide a patch if needed for the above, but perhaps there's another preferred alternative?

For references, here's my proxy configuration:

ProxyBadHeader Ignore                                                           
<Location "/cable/">                                                            
  ProxyPass http://192.168.100.1/                                               
</Location>