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.