You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ti...@apache.org on 2010/10/04 22:33:57 UTC
svn commit: r1004409 -
/tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java
Author: timw
Date: Mon Oct 4 20:33:57 2010
New Revision: 1004409
URL: http://svn.apache.org/viewvc?rev=1004409&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50026 for WebdavServlet
Factored checking of special WEB-INF and META-INF paths into service to trap requests for GET methods handled by DefaultServlet (which does not check access).
Retained checking of special paths in handlers for copy, delete, move (copy + delete), and in enumeration of resources (propfind).
Modified:
tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java
Modified: tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java?rev=1004409&r1=1004408&r2=1004409&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java Mon Oct 4 20:33:57 2010
@@ -71,42 +71,46 @@ import org.xml.sax.SAXException;
* Servlet which adds support for WebDAV level 2. All the basic HTTP requests
* are handled by the DefaultServlet. The WebDAVServlet must not be used as the
* default servlet (ie mapped to '/') as it will not work in this configuration.
- * To enable WebDAV for a context add the following to web.xml:<br/><code>
- * <servlet><br/>
- * <servlet-name>webdav</servlet-name><br/>
- * <servlet-class>org.apache.catalina.servlets.WebdavServlet</servlet-class><br/>
- * <init-param><br/>
- * <param-name>debug</param-name><br/>
- * <param-value>0</param-value><br/>
- * </init-param><br/>
- * <init-param><br/>
- * <param-name>listings</param-name><br/>
- * <param-value>true</param-value><br/>
- * </init-param><br/>
- * </servlet><br/>
- * <servlet-mapping><br/>
- * <servlet-name>webdav</servlet-name><br/>
- * <url-pattern>/*</url-pattern><br/>
- * </servlet-mapping>
- * </code>
* <p/>
- * This will enable read only access. To enable read-write access add:<br/>
- * <code>
- * <init-param><br/>
- * <param-name>readonly</param-name><br/>
- * <param-value>false</param-value><br/>
- * </init-param><br/>
- * </code>
+ * Mapping a subpath (e.g. <code>/webdav/*</code> to this servlet has the effect
+ * of re-mounting the entire web application under that sub-path, with WebDAV
+ * access to all the resources. This <code>WEB-INF</code> and <code>META-INF</code>
+ * directories are protected in this re-mounted resource tree.
* <p/>
- * To make the content editable via a different URL, using the following
- * mapping:<br/>
- * <code>
- * <servlet-mapping><br/>
- * <servlet-name>webdav</servlet-name><br/>
- * <url-pattern>/webdavedit/*</url-pattern><br/>
+ * To enable WebDAV for a context add the following to web.xml:
+ * <pre>
+ * <servlet>
+ * <servlet-name>webdav</servlet-name>
+ * <servlet-class>org.apache.catalina.servlets.WebdavServlet</servlet-class>
+ * <init-param>
+ * <param-name>debug</param-name>
+ * <param-value>0</param-value>
+ * </init-param>
+ * <init-param>
+ * <param-name>listings</param-name>
+ * <param-value>false</param-value>
+ * </init-param>
+ * </servlet>
+ * <servlet-mapping>
+ * <servlet-name>webdav</servlet-name>
+ * <url-pattern>/*</url-pattern>
* </servlet-mapping>
- * </code>
- * <p/>
+ * </pre>
+ * This will enable read only access. To enable read-write access add:
+ * <pre>
+ * <init-param>
+ * <param-name>readonly</param-name>
+ * <param-value>false</param-value>
+ * </init-param>
+ * </pre>
+ * To make the content editable via a different URL, use the following
+ * mapping:
+ * <pre>
+ * <servlet-mapping>
+ * <servlet-name>webdav</servlet-name>
+ * <url-pattern>/webdavedit/*</url-pattern>
+ * </servlet-mapping>
+ * </pre>
* Don't forget to secure access appropriately to the editing URLs. With this
* configuration the context will be accessible to normal users as before. Those
* users with the necessary access will be able to edit content available via
@@ -315,10 +319,21 @@ public class WebdavServlet
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- String method = req.getMethod();
+ final String path = getRelativePath(req);
+
+ // Block access to special subdirectories.
+ // DefaultServlet assumes it services resources from the root of the web app
+ // and doesn't add any special path protection
+ // WebdavServlet remounts the webapp under a new path, so this check is
+ // necessary on all methods (including GET).
+ if (isSpecialPath(path)) {
+ resp.sendError(WebdavStatus.SC_NOT_FOUND);
+ return;
+ }
+
+ final String method = req.getMethod();
if (debug > 0) {
- String path = getRelativePath(req);
log("[" + method + "] " + path);
}
@@ -345,6 +360,19 @@ public class WebdavServlet
/**
+ * Checks whether a given path refers to a resource under
+ * <code>WEB-INF</code> or <code>META-INF</code>.
+ * @param path the full path of the resource being accessed
+ * @return <code>true</code> if the resource specified is under a special path
+ */
+ private static final boolean isSpecialPath(final String path) {
+ // FIXME: why isn't this just equalsIgnoreCase?
+ return path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")
+ || path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF");
+ }
+
+
+ /**
* Check if the conditions specified in the optional If headers are
* satisfied.
*
@@ -442,12 +470,6 @@ public class WebdavServlet
if (path.endsWith("/"))
path = path.substring(0, path.length() - 1);
- if ((path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")) ||
- (path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))) {
- resp.sendError(WebdavStatus.SC_FORBIDDEN);
- return;
- }
-
// Properties which are to be displayed.
Vector<String> properties = null;
// Propfind depth
@@ -719,12 +741,6 @@ public class WebdavServlet
String path = getRelativePath(req);
- if ((path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")) ||
- (path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))) {
- resp.sendError(WebdavStatus.SC_FORBIDDEN);
- return;
- }
-
boolean exists = true;
try {
resources.lookup(path);
@@ -1601,20 +1617,14 @@ public class WebdavServlet
if (debug > 0)
log("Dest path :" + destinationPath);
- if ((destinationPath.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")) ||
- (destinationPath.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))) {
+ // Check destination path to protect special subdirectories
+ if (isSpecialPath(destinationPath)) {
resp.sendError(WebdavStatus.SC_FORBIDDEN);
return false;
}
String path = getRelativePath(req);
- if ((path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")) ||
- (path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))) {
- resp.sendError(WebdavStatus.SC_FORBIDDEN);
- return false;
- }
-
if (destinationPath.equals(path)) {
resp.sendError(WebdavStatus.SC_FORBIDDEN);
return false;
@@ -1810,12 +1820,6 @@ public class WebdavServlet
HttpServletResponse resp, boolean setStatus)
throws IOException {
- if ((path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")) ||
- (path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))) {
- resp.sendError(WebdavStatus.SC_FORBIDDEN);
- return false;
- }
-
String ifHeader = req.getHeader("If");
if (ifHeader == null)
ifHeader = "";
@@ -1895,8 +1899,8 @@ public class WebdavServlet
if (debug > 1)
log("Delete:" + path);
- if ((path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF")) ||
- (path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))) {
+ // Prevent deletion of special subdirectories
+ if (isSpecialPath(path)) {
errorList.put(path, new Integer(WebdavStatus.SC_FORBIDDEN));
return;
}
@@ -2034,9 +2038,7 @@ public class WebdavServlet
Vector<String> propertiesVector) {
// Exclude any resource in the /WEB-INF and /META-INF subdirectories
- // (the "toUpperCase()" avoids problems on Windows systems)
- if (path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF") ||
- path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))
+ if (isSpecialPath(path))
return;
CacheEntry cacheEntry = resources.lookupCache(path);
@@ -2327,9 +2329,7 @@ public class WebdavServlet
Vector<String> propertiesVector) {
// Exclude any resource in the /WEB-INF and /META-INF subdirectories
- // (the "toUpperCase()" avoids problems on Windows systems)
- if (path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF") ||
- path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"))
+ if (isSpecialPath(path))
return;
// Retrieving the lock associated with the lock-null resource
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org