July 2013
Please note that republishing this article in full or in part is only allowed under the conditions described here.
Dubious HTTP III - Playing With Content-Length
The Content-Length header describes the size of the content, so there should be at most one. But what happens, when multiple Content-length headers get sent?
To determine the behavior of the browsers I tested with:
- Microsoft Internet Explorer (MSIE) versions 8 and 10
- Firefox 22
- Google Chrome 28
- Opera 12.16 (before WebKit)
- Rekonq (KDE project) 2.2.1 - Konqueror (KDE) seems to behave the same
To evaluate the behavior of intermediate systems I let virustotal.com (2013/7/10) check some URLs with dubious content-legth and checked against the HTTP proxy squid 3.2.1. I also looked at the source code of common IDS:
- Bro IDS 2.1
- Snort IDS 2.9.4.6
- Suricata IDS 1.4.3
To reproduce the results you might point your browser to my test site or set up your own using my test suite.
Sending same Content-Length twice
While there shouldn't be any unclear interpretation it looks like Suricata simply joins all headers of the same name separated by a comma and then tries to extract the digits. This fails because there is also a comma in the string, so Suricate complains and does not analyze content further.
Snort complains about the duplicate header and continues as if no content-length header was given.
All others use the given content-length.
Sending contradicting Content-Length headers
The behavior for different Content-Length headers varies a lot between the systems:
- Chrome and Firefox throw an error and will not load the content.
- Opera, Rekonq and MSIE will use the first Content-Length header
- Suricata will join the headers, find the resulting Content-Length invalid and stop processing response
- Snort will complain about the duplicate header and continues as if no content-length header was given (e.g. stop at eof)
- Bro and virustotal.co will silently use the latest Content-Length header
- squid will compare the headers and use the one with the largest value
Sending less data than promised by Content-length
While Chrome complains about the problem, all others just use the received data.
Conclusion
Yet again it is easy for an attacker, who manages its own web server, to bypass security systems by using content-length for dubious HTTP responses.
Corrections, Updates...
- 2013/07/11 - I have log entries from an Chrome Browser behind a Cisco IronPort, which indicate, that at least Cisco IronPort WSA/7.51 changes the HTTP header when contradicting Content-Length are used, so that the protected system gets non-ambigious data. From the logs I would guess that it simply removes all Content-Length headers, so that the response will be closed with eof.