Please note that republishing this article in full or in part is only allowed under the conditions described here.
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 220.127.116.11
- Suricata IDS 1.4.3
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.
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
While Chrome complains about the problem, all others just use the received data.
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.
- 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.