remm 00/12/11 09:07:27
Modified: catalina/src/share/org/apache/catalina/servlets
DefaultServlet.java
Log:
- Fix a security problem where /WEB-INF could be accessed using a path like
//WEB-INF. Now, the path is normalized before checking for /WEB-INF.
Revision Changes Path
1.16 +71 -6
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java
Index: DefaultServlet.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- DefaultServlet.java 2000/11/15 01:08:23 1.15
+++ DefaultServlet.java 2000/12/11 17:07:25 1.16
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
1.15 2000/11/15 01:08:23 remm Exp $
- * $Revision: 1.15 $
- * $Date: 2000/11/15 01:08:23 $
+ * $Header:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
1.16 2000/12/11 17:07:25 remm Exp $
+ * $Revision: 1.16 $
+ * $Date: 2000/12/11 17:07:25 $
*
* ====================================================================
*
@@ -112,7 +112,7 @@
*
* @author Craig R. McClanahan
* @author Remy Maucherat
- * @version $Revision: 1.15 $ $Date: 2000/11/15 01:08:23 $
+ * @version $Revision: 1.16 $ $Date: 2000/12/11 17:07:25 $
*/
public class DefaultServlet
@@ -719,6 +719,69 @@
}
+ /**
+ * 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) {
+
+ // Normalize the slashes and add leading slash if necessary
+ String normalized = path;
+ 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 "%20" in the normalized path
+ while (true) {
+ int index = normalized.indexOf("%20");
+ if (index < 0)
+ break;
+ normalized = normalized.substring(0, index) + " " +
+ normalized.substring(index + 3);
+ }
+
+ // 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);
+
+ }
+
+
// -------------------------------------------------------- Private Methods
@@ -1224,8 +1287,10 @@
// Exclude any resource in the /WEB-INF and /META-INF subdirectories
// (the "toUpperCase()" avoids problems on Windows systems)
- if (path.toUpperCase().startsWith("/WEB-INF") ||
- path.toUpperCase().startsWith("/META-INF")) {
+ String normalizedPath = normalize(path);
+ if ((normalizedPath == null) ||
+ normalizedPath.toUpperCase().startsWith("/WEB-INF") ||
+ normalizedPath.toUpperCase().startsWith("/META-INF")) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, path);
return;
}