5

Is Tomcat affected by this vulnerability? Here is the advisory announcement.

Shane Madden
  • 112,982
  • 12
  • 174
  • 248
Tom G
  • 81
  • 2
  • 3

3 Answers3

10

Essentially, this vulnerability gets the Apache server to build a massive response to a request for a single file, far larger than the file itself. While the RFC (2616) tells web services to accept multiple ranges, there's nothing saying that you can't have the ranges overlap. Bad implementation on Apache's part, but there's a good chance that other web servers are vulnerable.

Most Tomcat servlets don't allow Range requests, since it's a custom implementation of a filter to spew the right chunks of content. However, the default servlet (which handles static content) is another story.

Current Tomcat code (here) accepts multiple range sets, validates each one individually that it's within the bounds of the file's size, and plops it in a list of ranges to serve. However, the ranges are streamed out in sequence from the servlet's internal cache, and the process should be stopped immediately if the client requesting the data disconnects; in most cases, this should make the overlapping range request roughly equivalent to the performance impact of serving a large file.


And, to confirm, a quick test..

We'll send a quick request against / to get the size..

request:

HEAD / HTTP/1.1
Host: 192.168.100.200
Accept-Encoding: gzip
Connection: close

response:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"1887-1314245401000"
Last-Modified: Thu, 25 Aug 2011 04:10:01 GMT
Content-Type: text/html
Content-Length: 1887
Date: Thu, 25 Aug 2011 04:18:05 GMT
Connection: close

Verdict is, 1887 bytes for the cute little "It works!" page. That tells us the range we can use without Tomcat throwing away the range as out of bounds.

Ok, so let's check for whether it allows a quick overlap, bytes 0 to 10 then 5 to 15:

request:

GET / HTTP/1.1
Host: 192.168.100.200
Range: bytes=0-10,5-15
Accept-Encoding: gzip
Connection: close

response:

HTTP/1.1 206 Partial Content
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"1887-1314245401000"
Last-Modified: Thu, 25 Aug 2011 04:10:01 GMT
Content-Type: multipart/byteranges; boundary=CATALINA_MIME_BOUNDARY
Content-Length: 224
Date: Thu, 25 Aug 2011 04:17:11 GMT
Connection: close


--CATALINA_MIME_BOUNDARY
Content-Type: text/html
Content-Range: bytes 0-10/1887

<?xml versi
--CATALINA_MIME_BOUNDARY
Content-Type: text/html
Content-Range: bytes 5-15/1887

 version="1
--CATALINA_MIME_BOUNDARY--

Yup, sure enough - <?xml versi and version="1. So overlapping works.

And, whether it'll allow a request for more data than is actually in the file being served:

request:

GET / HTTP/1.1
Host: 192.168.100.200
Range: bytes=0-1800,1-1886
Accept-Encoding: gzip
Connection: close

response:

HTTP/1.1 206 Partial Content
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"1887-1314245401000"
Last-Modified: Thu, 25 Aug 2011 04:10:01 GMT
Content-Type: multipart/byteranges; boundary=CATALINA_MIME_BOUNDARY
Content-Length: 3893
Date: Thu, 25 Aug 2011 04:19:51 GMT
Connection: close


--CATALINA_MIME_BOUNDARY
Content-Type: text/html
Content-Range: bytes 0-1800/1887

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Apache Tomcat</title>
</head>

...(lots more data)...

Yup - nearly 4KB served of a sub-2KB file.

Amplify this approach to include an enormous number of ranges, and this is the basic structure of the attack. In Tomcat's case, the real impact seems to be that it allows an attacker to get a large amount of data served in response to a request for a relatively small resource, which may prove helpful in targeting bandwidth for a denial of service. I'd also be suspicious of the impacts in other edge cases; with a reverse proxy attempting to cache 206 responses, or when the requested resource is a file larger than would fit in the Tomcat cache.

Shane Madden
  • 112,982
  • 12
  • 174
  • 248
  • Kudos for actually digging into the code... – womble Aug 25 '11 at 04:56
  • Do you think that max heap size or tomcat's lower thread defaults might help tomcat in this case (or at least prevent swapping from occurring on the physical server)? – mahnsc Aug 25 '11 at 18:42
  • @mahnsc Tough to say without really hitting it and seeing how it responds - my gut feeling is to say that the java sandbox, heap size especially, will prevent it from completely exhausting a server's resource the way Apache does when hit with this, but that's just speculation. – Shane Madden Aug 26 '11 at 05:51
  • Nevertheless, that sounds like enough to launch a DOS attack on Tomcat, if not the entire server. – Dana the Sane Sep 15 '11 at 15:25
2

Its not a vulnerability. read the Default servlet code. It loads the resource once. It also reads all the range offsets. Then it iterates through all the offsets serving the content bases on the original resource. Which is DIFFERENT as to how apache httpd did it. So it will not trigger an OOM exception.

You could argue that you could send a LARGE AMOUNT of Range headers to make an exhaustive list or ranges to return. But that is a specific example of a DOS attack on sending too many headers. In which case tomcat and httpd have ways to limit too many request headers as well as their size.

--update Oct 4, 2011--
Tomcat could be open to an attack where a connection can be held open longer than normal. But this type of attack is no different than your standard DOS attack. It just allows the attacker to be "more efficient" by making a request serve more bytes than it normally would serve.

The only extra resources consumed by such an attack is bandwidth and open socket connections. So it is no different than a standard DOS attack. The only difference is the attacker can be slightly more efficient. But you haven't gained any extra protection by having Tomcat try to perform extra validations on the range.

Tim Funk
  • 436
  • 2
  • 4
  • The crux of the "vulnerability" is the acceptance of overlapping ranges in strict compliance with an RFC; it's behaving correctly, and that opens it to attack; whether to call that a "vulnerability" is a semantic discussion. The default servlet will gladly serve a large number overlapping ranges (all in one header), generating a response much larger than the actual resource being requested. It doesn't seem to do that in a way that's as cripplingly resource intensive as it is with Apache, but, [less susceptible still means susceptible](http://serverfault.com/q/317226). – Shane Madden Sep 30 '11 at 18:42
  • Hmm. Just saw that the reason you posted this here was because of a bug being filed against Tomcat based solely on my answer - sorry about that. As I tried to make clear in my post, it serves overlapping ranges happily, but that doesn't mean that it'll bring a Tomcat server to its knees any more quickly than a normal request would - and that I hadn't tested the real performance impact. Though, regardless, I'd still have some concerns about allowing unlimited overlapping ranges (a setup with a proxy that didn't RST its backend connection when the client dropped would crumple, for instance). – Shane Madden Oct 01 '11 at 06:30
  • (re: edit) That's a fair assessment. I'd still argue for validation code stopping overlapping ranges, as I'd be concerned for deployments that include proxy servers that try to cache 206 responses.. but, I'll edit my answer to make the actual impact more clear. – Shane Madden Oct 04 '11 at 14:49
1

tl;dr: Probably not.

Given that Apache httpd and Tomcat are different products, and I can't find mention of an equivalent vulnerability announcement in Tomcat, I'd lean towards "no". There's no details in the announcement as to what the exact bug is, so it's hard to say if it's likely that this could be a common programming bug, or something really quite specific to Apache httpd.

womble
  • 95,029
  • 29
  • 173
  • 228