You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Larry Isaacs <La...@sas.com> on 2000/07/07 23:17:01 UTC

[PATCH] Use of ".." disallowed even when not leaving the web appl ication

With the current Tomcat 3.2, a JSP page in a subdirectory of a web application can't use something like:

	<%@ include file="../header.jsp" %>

otherwise you get a jasper "Cannot read file" ParseException.  This used to work under Tomcat 3.1.  This may generate a fair amount of activity on the tomcat-user list asking "Why doesn't this work?" since the resulting error doesn't make it obvious that this is currently the implemented behavior.

The following patch restores this functionality while still preventing access outside of the web application. With this patch on my NT system, I can modify "webapps/jsp-tests/jsp/core-syntax/directives/include/positiveIncludeRel.jsp" to use:

	<%@ include file = ".././..//..///././../jsp/core_syntax/directives/../directives/include///././/../include/includecommon.html" %>

and Watchdog will still correctly pass.  Changing it to use:

	<%@ include file = ".././..//..///././../../jsp-tests/jsp/core_syntax/directives/../directives/include///././/../include/includecommon.html" %>

and Watchdog correctly fails.

I don't know if there was more to the security issues than preventing a URL from leaving the web application root.  If so, I'm willing to look into these issues too.

Cheers,
Larry 

========== FileUtil.java patchfile ==========
--- FileUtil.java.orig	Fri Jul 07 03:21:00 2000
+++ FileUtil.java	Fri Jul 07 13:57:27 2000
@@ -130,12 +130,39 @@
     */
     public static String safePath( String base, String path ) {
 	// Hack for Jsp ( and other servlets ) that use rel. paths 
-	if( ! path.startsWith("/") ) path="/"+ path;
-
 	String normP=path;
 	if( path.indexOf('\\') >=0 )
 	    normP= path.replace('\\', '/');
-	
+
+	if( ! normP.startsWith("/") ) normP="/"+ normP;
+
+	int index = normP.indexOf("/../");
+	if (index >= 0) {
+		// clean out "//" and "/./" so they won't be confused with real parent directories
+		int index2 = 0;
+		while ((index2 = normP.indexOf("//",index2)) >= 0) {
+			normP = normP.substring(0,index2) + normP.substring(index2 + 1);
+			if (index2 < index)
+				index--;
+		}
+		index2 = 0;
+		while ((index2 = normP.indexOf("/./",index2)) >= 0) {
+			normP = normP.substring(0,index2) + normP.substring(index2 + 2);
+			if (index2 < index)
+				index -= 2;
+		}
+		// remove "/<dir>/../"'s
+		while (index >= 0) {
+			// if no parent dir to remove, return null
+			if (index == 0)
+				// trying to leave context
+				return null;
+			index2 = normP.lastIndexOf('/',index - 1);
+			normP = normP.substring(0,index2) + normP.substring(index + 3);
+			index = normP.indexOf("/../",index2);
+		}	
+	}
+
 	String realPath= base + normP;
 
 	// Probably not needed - it will be used on the local FS
=============================================

__________
Larry Isaacs		
Larry.Isaacs@sas.com
SAS Institute Inc.