Tomcat / ApacheHTTPD encoded slashes problem

A recent project has involved building a widget that would be deployed to various websites.  Because of the types of requests that could be coming in to our Tomcat server – and our desire to be as RESTful as possible – we discovered that we would potentially have situations where encoded slashes would come in as a part of our API URL.

An example would be a get product call “api/v1/products/someProductIdentifier” where the product identifier has slashes in it (eg. api/v1/products/123/456/789), or a parameter that is Base64 encoded (Base64 encoding produces results containing any letter, number, or the + and / symbols; see http://msdn.microsoft.com/en-us/library/cc422512.aspx)

After some research into the issue and related security implications (http://tomcat.apache.org/tomcat-7.0-doc/security-howto.html#System_Properties), we added 2 runtime parameters to our Tomcat instance:

-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true

This allowed us to URIEncode the components of our URL and to successfuly send requests with slashes to our Tomcat server.

A new wrinkle came about when deploying to some of our other boxes that were using Apache HTTPD in front of Tomcat.  Apache HTTPD also blocks requests with encoded slashes so we had to make another configuation change.  In out .conf file we had to include the AllowEncodedSlashes directive (http://httpd.apache.org/docs/2.2/mod/core.html#allowencodedslashes):

<VirtualHost *:80>
   ServerName ourServerName\br
   AllowEncodedSlashes On
   ...
</VirtualHost>

Because we are using Apache HTTPD 2.2.15 we were unable to use the “AllowEncodedSlashes NoDecode” option (it wasn’t introduces until later).  This presented another problem as the slashes were now being decoded before sending to Tomcat/Jersey – where they were now failing.  Fortunately there was another option available to us.  In the Location tag of our Apache HTTPD .conf file we were able to add an additional “nocanon” argument to our ProxyPass:

<Location /someLocation >
   ProxyPass http://localhost:8080/ nocanon
   ...
</Location>

This allowed the encoded slashes to correctly pass through to Tomcat and eventually to Jersey.

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn