The HTTP "Range" Header
One of the topics we cover in our "Defending Web Applications" class is how to secure static files. For example, you are faced with multiple PDFs with confidential information, and you need to integrate authorization to read these PDFs into your web application. The standard solution involves two steps:
- Move the file out of the document root
- create a script that will perform the necessary authorization and then stream the file back to the user
Typically, the process of streaming the file back to the user is pretty simple. Most languages offer the ability to read the file, and then echo it back to the browser. In some cases, like for example PHP, there is a special command for this (readfile). This makes writing these access control scripts pretty easy, until you are faced with a new twist, the "Range" header.
The "Range" header is meant to be used to support partial downloads. A client may request just part of a file, instead of asking for the entire file.
RFC 2616 is a bit ambiguous when it comes to "Range" headers. First of all, it introduces the "Accept-Ranges" header, which can be used by the server to signal that it supports the "Range" header. Next, it states that the client may send a request using a "Range" header anyway, even if the server doesn't advertise support for it. The server also has the option to send "Accept-Ranges: none" to explicitly state that it does not support this type of header.
So what's the problem? It turns out that different HTTP clients appear to deal with "Range" headers slightly differently. In particular the iOS Podcast client requires support for the Range header, and will only download parts of the file if they are not supported. Apple recently advised iTunes publishers of this issue and requires content to be hosted on servers that support the Range header.
For a server, this is usually not a problem, wouldn't it be for a recent Apache DoS attack that caused some to block Range requests. Also, our "file streaming" script now needs to support the range requests.
Here is a quick outline of how to support "Range" requests properly:
-
Figure out if the Range header is used and extract the requested range. The range header should look like:
Range: bytes=1234-5678
but could look like:
Range: bytes=0-
If the upper end is missing, it is assumed to empty "until the end of the file".
-
load the file (if possible, only the part that needs to be send)
-
Send the file, but use a "206 Partial Content" response code. Also, add the "Content-Range" header to indicate what you are sending.
Content-Range: bytes 1234-5678/1234567 (start-end/total size). One interesting twist: The "size" is indicated in bytes, while the range is indicated as an offset. So the maximum "Range" is the size-1.
Aside from the annoyance of having to write a more complex script, why does this matter for security?
Think Intrusion Detection systems, and maybe even web application firewalls: It is now for example possible for an attacker to request your secret document one byte at a time, possibly defeating data leakage protection. Or an attacker streaming an exploit from a web server could do so in small chunks to again defeat content filtering by the client. I played with various overlapping ranges and such, and it looks like browsers will discard these requests as they should.
It is also possible to specify multiple ranges in one request (which is what the Apache DoS was about), but so far I haven't observed any requests like this.
In short: watch it but don't block it. It may make sense to log and pay attention to Range requests, but you shouldn't blindly block all of them as they may be required by the browser/http client.
References:
RFC 2616: http://www.rfc-editor.org/rfc/rfc2616.txt
------
Johannes B. Ullrich, Ph.D.
SANS Technology Institute
Twitter
Firefox 20 and Thunderbird 17.0.5 updates
Thanks Mike and others for sending it through Some security fixes in both. Details are at the following links.
M
Comments
Anonymous
Dec 3rd 2022
9 months ago
Anonymous
Dec 3rd 2022
9 months ago
<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure. The social networks are not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go.
<a hreaf="https://technolytical.com/">the social network</a> is not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go. The social networks only collect the minimum amount of information required for the service that they provide. Your personal information is kept private, and is never shared with other companies without your permission
Anonymous
Dec 26th 2022
8 months ago
Anonymous
Dec 26th 2022
8 months ago
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> nearest public toilet to me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
Anonymous
Dec 26th 2022
8 months ago
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> nearest public toilet to me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
Anonymous
Dec 26th 2022
8 months ago
Anonymous
Dec 26th 2022
8 months ago
https://defineprogramming.com/
Dec 26th 2022
8 months ago
distribute malware. Even if the URL listed on the ad shows a legitimate website, subsequent ad traffic can easily lead to a fake page. Different types of malware are distributed in this manner. I've seen IcedID (Bokbot), Gozi/ISFB, and various information stealers distributed through fake software websites that were provided through Google ad traffic. I submitted malicious files from this example to VirusTotal and found a low rate of detection, with some files not showing as malware at all. Additionally, domains associated with this infection frequently change. That might make it hard to detect.
https://clickercounter.org/
https://defineprogramming.com/
Dec 26th 2022
8 months ago
rthrth
Jan 2nd 2023
8 months ago