HTTP Range Header and Partial Downloads

Published: 2013-02-06
Last Updated: 2013-02-06 19:07:01 UTC
by Johannes Ullrich (Version: 1)
1 comment(s)

Last week, I was debugging the podcast access script, I came across some interesting behaviour regarding the "Range" header in HTTP requests. The purpose of the "Range" header is to allow for resumable downloads via HTTP. The client may ask the server to only sent a certain part of the page, instead of the entire response. Not all servers (or browsers) necessarily support this feature. The feature is very different from "Chunked encoding", another feature that can be used to break up a page, but not to break it up as demanded by the client.

Client Side / Request

A request may include a range header, asking only for a part of the file. For example:

Range: bytes=0-100

would request the first 100 bytes from the response. The server may ignore this header, and the browser should accept whatever comes back, even if it is more or less then the requested range

Server Side / Response

A partial response always uses the status code 206 instead of 200. In addition, a header indicating the range delivered, and the total length of the file will be included:

From the RFC:

 

HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif

The Content-Range header indicates the range delivered, and the number following the / is the size of the file. In addition, you should still see a content-length header.

So what could possibly go wrong? I played with various invalid combinations, and so far, what I found is that the browser will ignore them. I haven't gotten around to test them all with respect to an IDS, but assume that a properly configured HTTP preprocessor will reassemble these ranges. Of course, without preprocessor, there will be a wide range of evasion/insertion attacks.

An issue I found is that some podcast clients will first try to download byte range 0-1, then they will download the file. Most of the time in one attempt, but frequently in multiple ranges. This can confuse web log analysis software as it will register them as multiple "hits" to the same file. You need at least to look at the status code (200 vs. 206). Also, the clients did not access the complete file if the server returned the entire file instead of just bytes 0-1. 

It is also possible to specify multiple byte ranges in one request, and older versions of Apache had a denial of service vulnerability if an excessive number of byte ranges was specified.

Let us know if you find anythingelse interesting when it comes to processing the Range header.

References: RFC 2616 http://www.w3.org/Protocols/rfc2616

------
Johannes B. Ullrich, Ph.D.
SANS Technology Institute
Twitter

Keywords: http range
1 comment(s)

Comments

At Smoothwall, we see a lot of issues with this sort of traffic going through our proxy product. My favourite is youtube on IOS, this app asks for a range, and if you give it back a 200 and the whole file, it can't cope. Oddly enough, youtube on Android doesn't suffer from this.

Diary Archives