Tomcat – Apache – How to limit Content-Type header length to avoid CVE-2014-0050

apache-2.2ddoshttpdtomcat

On Thursday a DoS problem with Tomcat was announced in a Tomcat mailing list ("[SECURITY] CVE-2014-0050 Apache Commons FileUpload and Apache Tomcat DoS").

An attacker seems to be able to cause an infinite loop by sending an overlong content-type header when uploading files (if the Servlet 3.0+ upload capability is used in the web application), as far as I understood the message at first glance.

If someone operates their Tomcat servers behind Apache httpd servers (using AJP and mod_jk), what could one do to implement the recommendation "Limit the size of the Content-Type header to less than 4091 bytes"?

Of course, as soon as a bugfix release is available (through the download page or Linux distribution specific package repositories), one should update. No question. But at the moment the currently available Tomcat version 7.0.50 seems to be still affected.

But what could one do as a quick defensive measure, until a fixed release is available?

(Without having to …

  • uninstall current Tomcat packages (installed from package repository),
  • build the versions manually from the sources (SVN),
  • deploy them manually (without apt-get or aptitude),
  • later uninstall all the manually built stuff again in favor of comfortably updateable versions from the package repository)

Are there ways similar to the temporary work-arounds for this topic: http://wiki.apache.org/httpd/CVE-2011-3192 ?

Back then, one could use mod_headers, mod_setenvif or mod_rewrite to deal with the problem. Are there similar Apache httpd tricks to keep the malformed multipart upload requests away from the downstream Tomcat server?

Best Answer

apache (including a modified version from Shane; reading the rfc i wouldnt bet the length of Content-String is always < 129

RewriteEngine On
RewriteCond %{HTTP:Content-Type} "multipart\/form-data;(\s*)boundary=[a-zA-Z0-9_-]{3000}"
RewriteRule ^/(.*)$ /405.html [R=301,L]

# modified 
SetEnvIf Content-Type ^.{3000,}$ bad-content-type=1
RequestHeader unset Content-Type env=bad-content-type

nginx (did not found a way around if() )

server {
  ...
  if ($http_content_type ~* "multipart\/form-data;(\s*)boundary=[a-zA-Z0-9_-]{3000}" ) {
  return 403; 
  }
  ...

}