6.3 Multiple Server Security Models
When sharing a physical directory of web pages between the Apache httpd web server and Tomcat on the same machine (or network filesystem), beware of interactions between their respective security models. This is particularly critical when you have "protected directories." If you're using the simplistic sharing modes detailed in Chapter 5, such as load sharing using separate port numbers or proxying from Apache to Tomcat, the servers have permission to read each others' files. In these cases, be aware that Tomcat does not protect files like .htaccess, and neither Apache httpd nor Microsoft's Internet Information Server (IIS) protect a web application's WEB-INF or META-INF directories. Either of these is likely to lead to a major security breach, so we recommend that you be very careful in working with these special directories. You should instead use one of the connector modules described in the latter sections of Chapter 5. These solutions are more complex, but they protect your WEB-INF and META-INF contents from view by the native web server.
To make Apache httpd protect your WEB-INF and META-INF directories, add the following to your httpd.conf:
<LocationMatch "/WEB-INF/"> AllowOverride None deny from all </LocationMatch> <LocationMatch "/META-INF/"> AllowOverride None deny from all </LocationMatch>
You can also configure Tomcat to send all .htaccess requests to an error page, but that's somewhat more difficult. In a stock Tomcat 4 installation, add a servlet-mapping to the end of the $CATALINA_HOME/conf/web.xml file's servlet-mapping entries:
<servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>*.htaccess</url-pattern> </servlet-mapping>
This maps all requests for .htaccess in all web applications to the invoker servlet, which in turn will generate an "HTTP 404: Not Found" error page because it can't load a servlet class by that name. Technically, this is bad form, since if Tomcat could find and load a class by the requested name (.htaccess), it might run that class instead of reporting an error. However, class names can't begin with a period, so this is a pretty safe solution.
Additionally, if you're not using the invoker servlet, you should disable it; if it's disabled, you can't map requests for specific names. The proper way to configure Tomcat not to serve .htaccess files is to write, compile, and configure a custom error-generating servlet to which you can map these forbidden requests. That is more of a programming topic; refer to a text such as Java Servlet Programming, by Jason Hunter (O'Reilly) for more details.