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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.tomcat:tomcatMaven | >= 4.1.0, < 4.1.40 | 4.1.40 |
org.apache.tomcat:tomcatMaven | >= 5.5.0, < 5.5.28 | 5.5.28 |
org.apache.tomcat:tomcatMaven | >= 6.0.0, < 6.0.20 | 6.0.20 |
Affected products
80cpe: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
16b61911f94d6Remove 3 of the essentially 4 duplicate normalise implementations.
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- jvn.jp/en/jp/JVN63832775/index.htmlnvdPatchWEB
- tomcat.apache.org/security-4.htmlnvdPatchVendor AdvisoryWEB
- tomcat.apache.org/security-5.htmlnvdPatchVendor AdvisoryWEB
- tomcat.apache.org/security-6.htmlnvdPatchVendor AdvisoryWEB
- www.securityfocus.com/bid/35263nvdPatch
- www.vupen.com/english/advisories/2009/1520nvdPatchVendor Advisory
- github.com/advisories/GHSA-9737-qmgc-hfr9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2008-5515ghsaADVISORY
- lists.apple.com/archives/security-announce/2010//Mar/msg00001.htmlnvdWEB
- lists.opensuse.org/opensuse-security-announce/2009-07/msg00002.htmlnvdWEB
- lists.opensuse.org/opensuse-security-announce/2010-04/msg00001.htmlnvdWEB
- marc.infonvdWEB
- marc.infonvdWEB
- marc.infonvdWEB
- support.apple.com/kb/HT4077nvdWEB
- www.debian.org/security/2011/dsa-2207nvdWEB
- www.fujitsu.com/global/support/software/security/products-f/interstage-200902e.htmlnvdWEB
- www.mandriva.com/security/advisoriesnvdWEB
- www.mandriva.com/security/advisoriesnvdWEB
- www.mandriva.com/security/advisoriesnvdWEB
- www.vmware.com/security/advisories/VMSA-2009-0016.htmlnvdWEB
- github.com/apache/tomcat/commit/6b61911f94d6d8d49ee933c5f1882a7e7c336d2cghsaWEB
- lists.apache.org/thread.html/06cfb634bc7bf37af7d8f760f118018746ad8efbd519c4b789ac9c2e%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/29dc6c2b625789e70a9c4756b5a327e6547273ff8bde7e0327af48c5%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/8dcaf7c3894d66cb717646ea1504ea6e300021c85bb4e677dc16b1aa%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/c62b0e3a7bf23342352a5810c640a94b6db69957c5c19db507004d74%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/r3aacc40356defc3f248aa504b1e48e819dd0471a0a83349080c6bcbf%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/r584a714f141eff7b1c358d4679288177bd4ca4558e9999d15867d4b5%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/rb71997f506c6cc8b530dd845c084995a9878098846c7b4eacfae8db3%40%3Cdev.tomcat.apache.org%3EnvdWEB
- oval.cisecurity.org/repository/search/definition/oval:org.mitre.oval:def:10422ghsaWEB
- oval.cisecurity.org/repository/search/definition/oval:org.mitre.oval:def:19452ghsaWEB
- oval.cisecurity.org/repository/search/definition/oval:org.mitre.oval:def:6445ghsaWEB
- www.redhat.com/archives/fedora-package-announce/2009-November/msg01156.htmlnvdWEB
- www.redhat.com/archives/fedora-package-announce/2009-November/msg01216.htmlnvdWEB
- www.redhat.com/archives/fedora-package-announce/2009-November/msg01246.htmlnvdWEB
- secunia.com/advisories/35393nvd
- secunia.com/advisories/35685nvd
- secunia.com/advisories/35788nvd
- secunia.com/advisories/37460nvd
- secunia.com/advisories/39317nvd
- secunia.com/advisories/42368nvd
- secunia.com/advisories/44183nvd
- sunsolve.sun.com/search/document.donvd
- www.securityfocus.com/archive/1/504170/100/0/threadednvd
- www.securityfocus.com/archive/1/504202/100/0/threadednvd
- www.securityfocus.com/archive/1/507985/100/0/threadednvd
- www.vupen.com/english/advisories/2009/1535nvd
- www.vupen.com/english/advisories/2009/1856nvd
- www.vupen.com/english/advisories/2009/3316nvd
- www.vupen.com/english/advisories/2010/3056nvd
- oval.cisecurity.org/repository/search/definition/oval%3Aorg.mitre.oval%3Adef%3A10422nvd
- oval.cisecurity.org/repository/search/definition/oval%3Aorg.mitre.oval%3Adef%3A19452nvd
- oval.cisecurity.org/repository/search/definition/oval%3Aorg.mitre.oval%3Adef%3A6445nvd
News mentions
0No linked articles in our index yet.