You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2025/01/15 09:42:44 UTC

(tomcat) branch main updated: More accurate check for WEB-INF and META-INF

This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 90a6e20ee6 More accurate check for WEB-INF and META-INF
90a6e20ee6 is described below

commit 90a6e20ee6e3a7d2bc7e213d8d92814b988c951e
Author: remm <re...@apache.org>
AuthorDate: Wed Jan 15 10:42:11 2025 +0100

    More accurate check for WEB-INF and META-INF
    
    Remove redundant checks already done in service().
    Avoid ISE with invalid paths in the if header.
    Based on a patch submitted by Chenjp.
---
 .../apache/catalina/servlets/WebdavServlet.java    | 26 ++++++++++------------
 webapps/docs/changelog.xml                         |  4 ++++
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java b/java/org/apache/catalina/servlets/WebdavServlet.java
index 280a325c2f..912a575ebf 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -610,6 +610,10 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
             if (hrefs.hasNext()) {
                 currentHref = hrefs.next();
                 currentPath = getPathFromHref(currentHref, request);
+                if (currentPath == null) {
+                    // The path was invalid
+                    return false;
+                }
                 currentWebResource = resources.getResource(currentPath);
             } else {
                 currentPath = path;
@@ -805,12 +809,6 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
 
         String path = getRelativePath(req);
 
-        // Exclude any resource in the /WEB-INF and /META-INF subdirectories
-        if (isSpecialPath(path)) {
-            resp.sendError(WebdavStatus.SC_FORBIDDEN);
-            return;
-        }
-
         // Properties which are to be displayed.
         List<Node> properties = new ArrayList<>();
         // Propfind depth
@@ -1197,12 +1195,6 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
 
         String path = getRelativePath(req);
 
-        // Exclude any resource in the /WEB-INF and /META-INF subdirectories
-        if (isSpecialPath(path)) {
-            resp.sendError(WebdavStatus.SC_FORBIDDEN);
-            return;
-        }
-
         WebResource resource = resources.getResource(path);
         if (!checkIfHeaders(req, resp, resource)) {
             resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
@@ -1852,8 +1844,14 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
      * @return <code>true</code> if the resource specified is under a special path
      */
     private boolean isSpecialPath(final String path) {
-        return !allowSpecialPaths && (path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF") ||
-                path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"));
+        if (!allowSpecialPaths) {
+            String upperCasePath = path.toUpperCase(Locale.ENGLISH);
+            if (upperCasePath.startsWith("/WEB-INF/") || upperCasePath.startsWith("/META-INF/")
+                    || upperCasePath.equals("/WEB-INF") || upperCasePath.equals("/META-INF")) {
+                return true;
+            }
+        }
+        return false;
     }
 
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 75aa0b7ff3..bdb7984084 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -163,6 +163,10 @@
         <code>bloom</code> <code>archiveIndexStrategy</code> of the
         <code>Resources</code>. (remm)
       </fix>
+      <fix>
+        Improve checks for <code>WEB-INF</code> and <code>META-INF</code> in
+        the WebDAV servlet. Based on a patch submitted by Chenjp. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: (tomcat) branch main updated: More accurate check for WEB-INF and META-INF

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Rémy,

On 1/15/25 4:42 AM, remm@apache.org wrote:
> This is an automated email from the ASF dual-hosted git repository.
> 
> remm pushed a commit to branch main
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
> 
> 
> The following commit(s) were added to refs/heads/main by this push:
>       new 90a6e20ee6 More accurate check for WEB-INF and META-INF
> 90a6e20ee6 is described below
> 
> commit 90a6e20ee6e3a7d2bc7e213d8d92814b988c951e
> Author: remm <re...@apache.org>
> AuthorDate: Wed Jan 15 10:42:11 2025 +0100
> 
>      More accurate check for WEB-INF and META-INF
>      
>      Remove redundant checks already done in service().
>      Avoid ISE with invalid paths in the if header.
>      Based on a patch submitted by Chenjp.
> ---
>   .../apache/catalina/servlets/WebdavServlet.java    | 26 ++++++++++------------
>   webapps/docs/changelog.xml                         |  4 ++++
>   2 files changed, 16 insertions(+), 14 deletions(-)
> 
> diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java b/java/org/apache/catalina/servlets/WebdavServlet.java
> index 280a325c2f..912a575ebf 100644
> --- a/java/org/apache/catalina/servlets/WebdavServlet.java
> +++ b/java/org/apache/catalina/servlets/WebdavServlet.java
> @@ -610,6 +610,10 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
>               if (hrefs.hasNext()) {
>                   currentHref = hrefs.next();
>                   currentPath = getPathFromHref(currentHref, request);
> +                if (currentPath == null) {
> +                    // The path was invalid
> +                    return false;
> +                }
>                   currentWebResource = resources.getResource(currentPath);
>               } else {
>                   currentPath = path;
> @@ -805,12 +809,6 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
>   
>           String path = getRelativePath(req);
>   
> -        // Exclude any resource in the /WEB-INF and /META-INF subdirectories
> -        if (isSpecialPath(path)) {
> -            resp.sendError(WebdavStatus.SC_FORBIDDEN);
> -            return;
> -        }
> -
>           // Properties which are to be displayed.
>           List<Node> properties = new ArrayList<>();
>           // Propfind depth
> @@ -1197,12 +1195,6 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
>   
>           String path = getRelativePath(req);
>   
> -        // Exclude any resource in the /WEB-INF and /META-INF subdirectories
> -        if (isSpecialPath(path)) {
> -            resp.sendError(WebdavStatus.SC_FORBIDDEN);
> -            return;
> -        }
> -
>           WebResource resource = resources.getResource(path);
>           if (!checkIfHeaders(req, resp, resource)) {
>               resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
> @@ -1852,8 +1844,14 @@ public class WebdavServlet extends DefaultServlet implements PeriodicEventListen
>        * @return <code>true</code> if the resource specified is under a special path
>        */
>       private boolean isSpecialPath(final String path) {
> -        return !allowSpecialPaths && (path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF") ||
> -                path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF"));
> +        if (!allowSpecialPaths) {
> +            String upperCasePath = path.toUpperCase(Locale.ENGLISH);
> +            if (upperCasePath.startsWith("/WEB-INF/") || upperCasePath.startsWith("/META-INF/")
> +                    || upperCasePath.equals("/WEB-INF") || upperCasePath.equals("/META-INF")) {
> +                return true;

I think this can be slightly faster if written like this:

if ( ( upperCasePath.startsWith("/WEB-INF")
        && (upperCasePath.length() == 8 || upperCasePath.charAt(8) == '/'))

     || ( upperCasePath.startsWith("/META-INF")
        && (upperCasePath.length() == 9 || upperCasePath.charAt(9) == '/'))
  ) {
...
}

It will only traverse the first part of the string 2 times in the worse 
case instead of 4 times.

It is more difficult to read, though.

-chris

> +            }
> +        }
> +        return false;
>       }
>   
>   
> diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
> index 75aa0b7ff3..bdb7984084 100644
> --- a/webapps/docs/changelog.xml
> +++ b/webapps/docs/changelog.xml
> @@ -163,6 +163,10 @@
>           <code>bloom</code> <code>archiveIndexStrategy</code> of the
>           <code>Resources</code>. (remm)
>         </fix>
> +      <fix>
> +        Improve checks for <code>WEB-INF</code> and <code>META-INF</code> in
> +        the WebDAV servlet. Based on a patch submitted by Chenjp. (remm)
> +      </fix>
>       </changelog>
>     </subsection>
>     <subsection name="Coyote">
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org