VYPR
Moderate severityNVD Advisory· Published Jun 16, 2009· Updated Apr 23, 2026

CVE-2008-5515

CVE-2008-5515

Description

Apache Tomcat 4.1.0 through 4.1.39, 5.5.0 through 5.5.27, 6.0.0 through 6.0.18, and possibly earlier versions normalizes the target pathname before filtering the query string when using the RequestDispatcher method, which allows remote attackers to bypass intended access restrictions and conduct directory traversal attacks via .. (dot dot) sequences and the WEB-INF directory in a Request.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.tomcat:tomcatMaven
>= 4.1.0, < 4.1.404.1.40
org.apache.tomcat:tomcatMaven
>= 5.5.0, < 5.5.285.5.28
org.apache.tomcat:tomcatMaven
>= 6.0.0, < 6.0.206.0.20

Affected products

80
  • Apache/Tomcat80 versions
    cpe:2.3:a:apache:tomcat:5.5.13:*:*:*:*:*:*:*+ 79 more
    • cpe:2.3:a:apache:tomcat:5.5.13:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.14:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.15:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.16:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.17:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.18:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.19:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.20:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.21:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.22:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.23:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.10:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.11:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.12:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.13:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.14:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.15:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.16:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.17:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.18:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.19:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.20:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.21:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.22:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.23:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.24:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.25:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.26:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.27:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.28:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.29:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.30:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.31:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.32:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.33:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.34:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.35:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.36:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.37:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.38:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:4.1.39:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.5:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.6:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.7:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.8:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.9:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.10:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.11:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.12:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.24:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.25:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.26:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:5.5.27:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.5:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.6:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.7:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.9:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.10:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.12:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.13:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.14:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.15:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.16:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.17:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:6.0.18:*:*:*:*:*:*:*

Patches

1
6b61911f94d6

Remove 3 of the essentially 4 duplicate normalise implementations.

https://github.com/apache/tomcatMark Emlyn David ThomasJan 15, 2009via ghsa
8 files changed · +40 166
  • java/org/apache/catalina/connector/Request.java+2 3 modified
    @@ -1297,10 +1297,9 @@ else if (path.startsWith("/"))
             int pos = requestPath.lastIndexOf('/');
             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));
    
  • java/org/apache/catalina/core/ApplicationContext.java+9 44 modified
    @@ -52,6 +52,7 @@
     import org.apache.catalina.deploy.FilterDef;
     import org.apache.catalina.deploy.FilterMap;
     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;
    @@ -410,7 +411,7 @@ public RequestDispatcher getRequestDispatcher(String path) {
                 path = path.substring(0, pos);
             }
     
    -        path = normalize(path);
    +        path = RequestUtil.normalize(path);
             if (path == null)
                 return (null);
     
    @@ -495,7 +496,7 @@ public URL getResource(String path)
                 throw new MalformedURLException(sm.getString("applicationContext.requestDispatcher.iae", path));
     
             
    -        path = normalize(path);
    +        path = RequestUtil.normalize(path);
             if (path == null)
                 return (null);
     
    @@ -544,13 +545,16 @@ public URL getResource(String path)
          */
         public InputStream getResourceAsStream(String path) {
     
    -        path = normalize(path);
             if (path == null)
                 return (null);
     
             if (!path.startsWith("/") && Globals.STRICT_SERVLET_COMPLIANCE)
                 return null;
    -        
    +
    +        path = RequestUtil.normalize(path);
    +        if (path == null)
    +            return (null);
    +
             DirContext resources = context.getResources();
             if (resources != null) {
                 try {
    @@ -583,7 +587,7 @@ public Set<String> getResourcePaths(String path) {
                     (sm.getString("applicationContext.resourcePaths.iae", path));
             }
     
    -        path = normalize(path);
    +        path = RequestUtil.normalize(path);
             if (path == null)
                 return (null);
     
    @@ -1056,45 +1060,6 @@ void setAttributeReadOnly(String name) {
         // -------------------------------------------------------- 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) {
    -
    -        if (path == null) {
    -            return null;
    -        }
    -
    -        String normalized = path;
    -
    -        // Normalize the slashes
    -        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
    
  • java/org/apache/catalina/core/ApplicationHttpRequest.java+2 3 modified
    @@ -318,10 +318,9 @@ else if (path.startsWith("/"))
             int pos = requestPath.lastIndexOf('/');
             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));
    
  • java/org/apache/catalina/servlets/WebdavServlet.java+3 64 modified
    @@ -1412,68 +1412,6 @@ protected void doUnlock(HttpServletRequest req, HttpServletResponse resp)
     
         }
     
    -    /**
    -     * 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;
    -
    -        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);
    -
    -    }
    -
    -
         // -------------------------------------------------------- Private Methods
     
         /**
    @@ -1628,7 +1566,7 @@ private boolean copyResource(HttpServletRequest req,
             }
     
             // Normalise destination path (remove '.' and '..')
    -        destinationPath = normalize(destinationPath);
    +        destinationPath = RequestUtil.normalize(destinationPath);
     
             String contextPath = req.getContextPath();
             if ((contextPath != null) &&
    @@ -2383,7 +2321,8 @@ private void parseLockNullProperties(HttpServletRequest req,
             if (!toAppend.startsWith("/"))
                 toAppend = "/" + toAppend;
     
    -        generatedXML.writeText(rewriteUrl(normalize(absoluteUri + toAppend)));
    +        generatedXML.writeText(rewriteUrl(RequestUtil.normalize(
    +                absoluteUri + toAppend)));
     
             generatedXML.writeElement(null, "href", XMLWriter.CLOSING);
     
    
  • java/org/apache/catalina/ssi/SSIServletExternalResolver.java+3 2 modified
    @@ -31,6 +31,7 @@
     import javax.servlet.http.HttpServletRequest;
     import javax.servlet.http.HttpServletResponse;
     import org.apache.catalina.connector.Request;
    +import org.apache.catalina.util.RequestUtil;
     import org.apache.coyote.Constants;
     
     /**
    @@ -370,7 +371,7 @@ protected String getAbsolutePath(String path) throws IOException {
                         + 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);
    @@ -403,7 +404,7 @@ protected ServletContextAndPath getServletContextAndPathFromVirtualPath(
                 return new ServletContextAndPath(context,
                         getAbsolutePath(virtualPath));
             } else {
    -            String normalized = SSIServletRequestUtil.normalize(virtualPath);
    +            String normalized = RequestUtil.normalize(virtualPath);
                 if (isVirtualWebappRelative) {
                     return new ServletContextAndPath(context, normalized);
                 } else {
    
  • java/org/apache/catalina/ssi/SSIServletRequestUtil.java+3 9 modified
    @@ -47,7 +47,7 @@ public static String getRelativePath(HttpServletRequest request) {
             if ((result == null) || (result.equals(""))) {
                 result = "/";
             }
    -        return normalize(result);
    +        return RequestUtil.normalize(result);
         }
     
     
    @@ -63,15 +63,9 @@ public static String getRelativePath(HttpServletRequest request) {
          * 
          * @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);
         }
     }
    \ No newline at end of file
    
  • java/org/apache/catalina/util/RequestUtil.java+16 0 modified
    @@ -93,13 +93,29 @@ public static String filter(String message) {
          * @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;
     
             // Create a place for the normalized path
             String normalized = path;
     
    +        if (replaceBackSlash && normalized.indexOf('\\') >= 0)
    +            normalized = normalized.replace('\\', '/');
    +
             if (normalized.equals("/."))
                 return "/";
     
    
  • java/org/apache/naming/resources/FileDirContext.java+2 41 modified
    @@ -40,6 +40,7 @@
     import javax.naming.directory.SearchControls;
     import javax.naming.directory.SearchResult;
     
    +import org.apache.catalina.util.RequestUtil;
     import org.apache.naming.NamingContextBindingsEnumeration;
     import org.apache.naming.NamingContextEnumeration;
     import org.apache.naming.NamingEntry;
    @@ -768,50 +769,10 @@ public NamingEnumeration<SearchResult> search(String name,
          */
         protected String normalize(String path) {
     
    -    String normalized = path;
    -
    -    // Normalize the slashes and add leading slash if necessary
    -    if (File.separatorChar == '\\' && 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);
    -    }
    +        return RequestUtil.normalize(path, File.separatorChar == '\\');
     
    -    // 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 a File object representing the specified normalized
          * context-relative path if it exists and is readable.  Otherwise,
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

53

News mentions

0

No linked articles in our index yet.