Author: markt Date: Mon Jun 8 20:14:37 2009 New Revision: 782763 URL: http://svn.apache.org/viewvc?rev=782763&view=rev Log: Port normalisation clean-up. Includes fix for CVE-2008-5515
Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/connector/HttpRequestBase.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationContext.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletRequestUtil.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/util/RequestUtil.java tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/naming/resources/FileDirContext.java Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/connector/HttpRequestBase.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/connector/HttpRequestBase.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/connector/HttpRequestBase.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/connector/HttpRequestBase.java Mon Jun 8 20:14:37 2009 @@ -759,10 +759,9 @@ String relative = null; if (pos >= 0) { - relative = RequestUtil.normalize - (requestPath.substring(0, pos + 1) + path); + relative = requestPath.substring(0, pos + 1) + path; } else { - relative = RequestUtil.normalize(requestPath + path); + relative = requestPath + path; } return (context.getServletContext().getRequestDispatcher(relative)); Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationContext.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationContext.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationContext.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationContext.java Mon Jun 8 20:14:37 2009 @@ -50,6 +50,7 @@ import org.apache.catalina.Wrapper; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.util.Enumerator; +import org.apache.catalina.util.RequestUtil; import org.apache.catalina.util.ResourceSet; import org.apache.catalina.util.ServerInfo; import org.apache.catalina.util.StringManager; @@ -590,7 +591,7 @@ path = path.substring(0, question); } - path = normalize(path); + path = RequestUtil.normalize(path); if (path == null) return (null); @@ -645,7 +646,7 @@ public URL getResource(String path) throws MalformedURLException { - path = normalize(path); + path = RequestUtil.normalize(path); if (path == null) return (null); @@ -689,7 +690,7 @@ */ public InputStream getResourceAsStream(String path) { - path = normalize(path); + path = RequestUtil.normalize(path); if (path == null) return (null); @@ -1045,42 +1046,6 @@ // -------------------------------------------------------- Private Methods - - /** - * Return a context-relative path, beginning with a "/", that represents - * the canonical version of the specified path after ".." and "." elements - * are resolved out. If the specified path attempts to go outside the - * boundaries of the current context (i.e. too many ".." path elements - * are present), return <code>null</code> instead. - * - * @param path Path to be normalized - */ - private String normalize(String path) { - - String normalized = path; - - // Normalize the slashes and add leading slash if necessary - if (normalized.indexOf('\\') >= 0) - normalized = normalized.replace('\\', '/'); - - // Resolve occurrences of "/../" in the normalized path - while (true) { - int index = normalized.indexOf("/../"); - if (index < 0) - break; - if (index == 0) - return (null); // Trying to go outside our context - int index2 = normalized.lastIndexOf('/', index - 1); - normalized = normalized.substring(0, index2) + - normalized.substring(index + 3); - } - - // Return the normalized path that we have completed - return (normalized); - - } - - /** * Merge the context initialization parameters specified in the application * deployment descriptor with the application parameters described in the Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java Mon Jun 8 20:14:37 2009 @@ -409,10 +409,9 @@ int pos = servletPath.lastIndexOf('/'); String relative = null; if (pos >= 0) { - relative = RequestUtil.normalize - (servletPath.substring(0, pos + 1) + path); + relative = servletPath.substring(0, pos + 1) + path; } else { - relative = RequestUtil.normalize(servletPath + path); + relative = servletPath + path; } return (context.getServletContext().getRequestDispatcher(relative)); Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java Mon Jun 8 20:14:37 2009 @@ -58,6 +58,7 @@ import org.apache.catalina.Globals; import org.apache.catalina.util.FastHttpDateFormat; import org.apache.catalina.util.MD5Encoder; +import org.apache.catalina.util.RequestUtil; import org.apache.catalina.util.ServerInfo; import org.apache.catalina.util.StringManager; import org.apache.catalina.util.URLEncoder; @@ -451,7 +452,7 @@ if ((result == null) || (result.equals(""))) { result = "/"; } - return normalize(result); + return RequestUtil.normalize(result); } @@ -756,80 +757,6 @@ /** - * Return a context-relative path, beginning with a "/", that represents - * the canonical version of the specified path after ".." and "." elements - * are resolved out. If the specified path attempts to go outside the - * boundaries of the current context (i.e. too many ".." path elements - * are present), return <code>null</code> instead. - * - * @param path Path to be normalized - */ - protected String normalize(String path) { - - if (path == null) - return null; - - // Create a place for the normalized path - String normalized = path; - - /* - * Commented out -- already URL-decoded in StandardContextMapper - * Decoding twice leaves the container vulnerable to %25 --> '%' - * attacks. - * - * if (normalized.indexOf('%') >= 0) - * normalized = RequestUtil.URLDecode(normalized, "UTF8"); - */ - - if (normalized == null) - return (null); - - if (normalized.equals("/.")) - return "/"; - - // Normalize the slashes and add leading slash if necessary - if (normalized.indexOf('\\') >= 0) - normalized = normalized.replace('\\', '/'); - if (!normalized.startsWith("/")) - normalized = "/" + normalized; - - // Resolve occurrences of "//" in the normalized path - while (true) { - int index = normalized.indexOf("//"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 1); - } - - // Resolve occurrences of "/./" in the normalized path - while (true) { - int index = normalized.indexOf("/./"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 2); - } - - // Resolve occurrences of "/../" in the normalized path - while (true) { - int index = normalized.indexOf("/../"); - if (index < 0) - break; - if (index == 0) - return (null); // Trying to go outside our context - int index2 = normalized.lastIndexOf('/', index - 1); - normalized = normalized.substring(0, index2) + - normalized.substring(index + 3); - } - - // Return the normalized path that we have completed - return (normalized); - - } - - - /** * URL rewriter. * * @param path Path which has to be rewiten Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java Mon Jun 8 20:14:37 2009 @@ -1535,7 +1535,7 @@ } // Normalise destination path (remove '.' and '..') - destinationPath = normalize(destinationPath); + destinationPath = RequestUtil.normalize(destinationPath); String contextPath = req.getContextPath(); if ((contextPath != null) && @@ -2296,7 +2296,8 @@ if (!toAppend.startsWith("/")) toAppend = "/" + toAppend; - generatedXML.writeText(rewriteUrl(normalize(absoluteUri + toAppend))); + generatedXML.writeText(rewriteUrl(RequestUtil.normalize( + absoluteUri + toAppend))); generatedXML.writeElement(null, "href", XMLWriter.CLOSING); Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java Mon Jun 8 20:14:37 2009 @@ -34,6 +34,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.catalina.util.RequestUtil; + /** * An implementation of SSIExternalResolver that is used with servlets. * @@ -239,7 +241,7 @@ throw new IOException("Couldn't remove filename from path: " + pathWithoutContext ); } String fullPath = prefix + path; - String retVal = SSIServletRequestUtil.normalize( fullPath ); + String retVal = RequestUtil.normalize( fullPath ); if ( retVal == null ) { throw new IOException("Normalization yielded null on path: " + fullPath ); @@ -271,7 +273,7 @@ if ( !virtualPath.startsWith("/") && !virtualPath.startsWith("\\") ) { path = getAbsolutePath( virtualPath ); } else { - String normalized = SSIServletRequestUtil.normalize( virtualPath ); + String normalized = RequestUtil.normalize( virtualPath ); if ( isVirtualWebappRelative ) { path = normalized; } else { Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletRequestUtil.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletRequestUtil.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletRequestUtil.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/ssi/SSIServletRequestUtil.java Mon Jun 8 20:14:37 2009 @@ -50,7 +50,7 @@ if ((result == null) || (result.equals(""))) { result = "/"; } - return normalize(result); + return RequestUtil.normalize(result); } /** @@ -64,20 +64,10 @@ * ( see source code below ) as RequestUtil.normalize. Do we need all this duplication? * * @param path Path to be normalized + * + * @deprecated */ public static String normalize(String path) { - if (path == null) - return null; - - String normalized = path; - - //Why doesn't RequestUtil do this?? - - // Normalize the slashes and add leading slash if necessary - if ( normalized.indexOf('\\') >= 0 ) - normalized = normalized.replace( '\\', '/' ); - - normalized = RequestUtil.normalize( path ); - return normalized; + return RequestUtil.normalize(path); } } Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/util/RequestUtil.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/util/RequestUtil.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/util/RequestUtil.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/catalina/util/RequestUtil.java Mon Jun 8 20:14:37 2009 @@ -146,6 +146,19 @@ * @param path Relative path to be normalized */ public static String normalize(String path) { + return normalize(path, true); + } + + /** + * Normalize a relative URI path that may have relative values ("/./", + * "/../", and so on ) it it. <strong>WARNING</strong> - This method is + * useful only for normalizing application-generated paths. It does not + * try to perform security checks for malicious input. + * + * @param path Relative path to be normalized + * @param replaceBackSlash Should '\\' be replaced with '/' + */ + public static String normalize(String path, boolean replaceBackSlash) { if (path == null) return null; @@ -153,6 +166,9 @@ // Create a place for the normalized path String normalized = path; + if (replaceBackSlash && normalized.indexOf('\\') >= 0) + normalized = normalized.replace('\\', '/'); + if (normalized.equals("/.")) return "/"; Modified: tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/naming/resources/FileDirContext.java URL: http://svn.apache.org/viewvc/tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/naming/resources/FileDirContext.java?rev=782763&r1=782762&r2=782763&view=diff ============================================================================== --- tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/naming/resources/FileDirContext.java (original) +++ tomcat/container/branches/tc4.1.x/catalina/src/share/org/apache/naming/resources/FileDirContext.java Mon Jun 8 20:14:37 2009 @@ -35,6 +35,8 @@ import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; + +import org.apache.catalina.util.RequestUtil; import org.apache.naming.NamingEntry; import org.apache.naming.NamingContextBindingsEnumeration; import org.apache.naming.NamingContextEnumeration; @@ -769,48 +771,7 @@ * @param path Path to be normalized */ protected String normalize(String path) { - - String normalized = path; - - // Normalize the slashes and add leading slash if necessary - if (normalized.indexOf('\\') >= 0) - normalized = normalized.replace('\\', '/'); - if (!normalized.startsWith("/")) - normalized = "/" + normalized; - - // Resolve occurrences of "//" in the normalized path - while (true) { - int index = normalized.indexOf("//"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 1); - } - - // Resolve occurrences of "/./" in the normalized path - while (true) { - int index = normalized.indexOf("/./"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 2); - } - - // Resolve occurrences of "/../" in the normalized path - while (true) { - int index = normalized.indexOf("/../"); - if (index < 0) - break; - if (index == 0) - return (null); // Trying to go outside our context - int index2 = normalized.lastIndexOf('/', index - 1); - normalized = normalized.substring(0, index2) + - normalized.substring(index + 3); - } - - // Return the normalized path that we have completed - return (normalized); - + return RequestUtil.normalize(path, File.separatorChar == '\\'); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org