Apache Tomcat: Potential RCE and/or information disclosure and/or information corruption with partial PUT
Description
Path Equivalence: 'file.Name' (Internal Dot) leading to Remote Code Execution and/or Information disclosure and/or malicious content added to uploaded files via write enabled Default Servlet in Apache Tomcat.
This issue affects Apache Tomcat: from 11.0.0-M1 through 11.0.2, from 10.1.0-M1 through 10.1.34, from 9.0.0.M1 through 9.0.98. The following versions were EOL at the time the CVE was created but are known to be affected: 8.5.0 though 8.5.100. Other, older, EOL versions may also be affected.
If all of the following were true, a malicious user was able to view security sensitive files and/or inject content into those files: - writes enabled for the default servlet (disabled by default) - support for partial PUT (enabled by default) - a target URL for security sensitive uploads that was a sub-directory of a target URL for public uploads - attacker knowledge of the names of security sensitive files being uploaded - the security sensitive files also being uploaded via partial PUT
If all of the following were true, a malicious user was able to perform remote code execution: - writes enabled for the default servlet (disabled by default) - support for partial PUT (enabled by default) - application was using Tomcat's file based session persistence with the default storage location - application included a library that may be leveraged in a deserialization attack
Users are recommended to upgrade to version 11.0.3, 10.1.35 or 9.0.99, which fixes the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.tomcat:tomcat-catalinaMaven | >= 11.0.0-M1, < 11.0.3 | 11.0.3 |
org.apache.tomcat:tomcat-catalinaMaven | >= 10.1.0-M1, < 10.1.35 | 10.1.35 |
org.apache.tomcat:tomcat-catalinaMaven | >= 9.0.0.M1, < 9.0.99 | 9.0.99 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 11.0.0-M1, < 11.0.3 | 11.0.3 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 10.1.0-M1, < 10.1.35 | 10.1.35 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 9.0.0.M1, < 9.0.99 | 9.0.99 |
org.apache.tomcat:tomcat-catalinaMaven | >= 8.5.0, <= 8.5.100 | — |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 8.5.0, <= 8.5.100 | — |
Affected products
1- Apache Software Foundation/Apache Tomcatv5Range: 11.0.0-M1
Patches
30a668e0c27f2Enhance lifecycle of temporary files used by partial PUT
2 files changed · +10 −10
java/org/apache/catalina/servlets/DefaultServlet.java+7 −10 modified@@ -602,7 +602,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se } InputStream resourceInputStream = null; - + File tempContentFile = null; try { // Append data specified in ranges to existing content for this // resource - create a temp. file on the local filesystem to @@ -611,8 +611,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se if (range == IGNORE) { resourceInputStream = req.getInputStream(); } else { - File contentFile = executePartialPut(req, range, path); - resourceInputStream = new FileInputStream(contentFile); + tempContentFile = executePartialPut(req, range, path); + resourceInputStream = new FileInputStream(tempContentFile); } if (resources.write(path, resourceInputStream, true)) { @@ -636,6 +636,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se // Ignore } } + if (tempContentFile != null) { + tempContentFile.delete(); + } } } @@ -658,13 +661,7 @@ protected File executePartialPut(HttpServletRequest req, ContentRange range, Str // resource - create a temp. file on the local filesystem to // perform this operation File tempDir = (File) getServletContext().getAttribute(ServletContext.TEMPDIR); - // Convert all '/' characters to '.' in resourcePath - String convertedResourcePath = path.replace('/', '.'); - File contentFile = new File(tempDir, convertedResourcePath); - if (contentFile.createNewFile()) { - // Clean up contentFile when Tomcat is terminated - contentFile.deleteOnExit(); - } + File contentFile = File.createTempFile("put-part-", null, tempDir); try (RandomAccessFile randAccessContentFile = new RandomAccessFile(contentFile, "rw")) {
webapps/docs/changelog.xml+3 −0 modified@@ -204,6 +204,9 @@ <code>IOException</code> occurs on a non-container thread during asynchronous processing. (markt) </fix> + <fix> + Enhance lifecycle of temporary files used by partial PUT. (remm) + </fix> </changelog> </subsection> <subsection name="Coyote">
f6c01d6577cfEnhance lifecycle of temporary files used by partial PUT
2 files changed · +10 −10
java/org/apache/catalina/servlets/DefaultServlet.java+7 −10 modified@@ -625,7 +625,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se } InputStream resourceInputStream = null; - + File tempContentFile = null; try { // Append data specified in ranges to existing content for this // resource - create a temp. file on the local filesystem to @@ -634,8 +634,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se if (range == IGNORE) { resourceInputStream = req.getInputStream(); } else { - File contentFile = executePartialPut(req, range, path); - resourceInputStream = new FileInputStream(contentFile); + tempContentFile = executePartialPut(req, range, path); + resourceInputStream = new FileInputStream(tempContentFile); } if (resources.write(path, resourceInputStream, true)) { @@ -659,6 +659,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se // Ignore } } + if (tempContentFile != null) { + tempContentFile.delete(); + } } } @@ -681,13 +684,7 @@ protected File executePartialPut(HttpServletRequest req, ContentRange range, Str // resource - create a temp. file on the local filesystem to // perform this operation File tempDir = (File) getServletContext().getAttribute(ServletContext.TEMPDIR); - // Convert all '/' characters to '.' in resourcePath - String convertedResourcePath = path.replace('/', '.'); - File contentFile = new File(tempDir, convertedResourcePath); - if (contentFile.createNewFile()) { - // Clean up contentFile when Tomcat is terminated - contentFile.deleteOnExit(); - } + File contentFile = File.createTempFile("put-part-", null, tempDir); try (RandomAccessFile randAccessContentFile = new RandomAccessFile(contentFile, "rw")) {
webapps/docs/changelog.xml+3 −0 modified@@ -181,6 +181,9 @@ <code>IOException</code> occurs on a non-container thread during asynchronous processing. (markt) </fix> + <fix> + Enhance lifecycle of temporary files used by partial PUT. (remm) + </fix> </changelog> </subsection> <subsection name="Coyote">
eb61aade8f8dEnhance lifecycle of temporary files used by partial PUT
2 files changed · +10 −10
java/org/apache/catalina/servlets/DefaultServlet.java+7 −10 modified@@ -625,7 +625,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se } InputStream resourceInputStream = null; - + File tempContentFile = null; try { // Append data specified in ranges to existing content for this // resource - create a temp. file on the local filesystem to @@ -634,8 +634,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se if (range == IGNORE) { resourceInputStream = req.getInputStream(); } else { - File contentFile = executePartialPut(req, range, path); - resourceInputStream = new FileInputStream(contentFile); + tempContentFile = executePartialPut(req, range, path); + resourceInputStream = new FileInputStream(tempContentFile); } if (resources.write(path, resourceInputStream, true)) { @@ -659,6 +659,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se // Ignore } } + if (tempContentFile != null) { + tempContentFile.delete(); + } } } @@ -681,13 +684,7 @@ protected File executePartialPut(HttpServletRequest req, Range range, String pat // resource - create a temp. file on the local filesystem to // perform this operation File tempDir = (File) getServletContext().getAttribute(ServletContext.TEMPDIR); - // Convert all '/' characters to '.' in resourcePath - String convertedResourcePath = path.replace('/', '.'); - File contentFile = new File(tempDir, convertedResourcePath); - if (contentFile.createNewFile()) { - // Clean up contentFile when Tomcat is terminated - contentFile.deleteOnExit(); - } + File contentFile = File.createTempFile("put-part-", null, tempDir); try (RandomAccessFile randAccessContentFile = new RandomAccessFile(contentFile, "rw")) {
webapps/docs/changelog.xml+3 −0 modified@@ -181,6 +181,9 @@ <code>IOException</code> occurs on a non-container thread during asynchronous processing. (markt) </fix> + <fix> + Enhance lifecycle of temporary files used by partial PUT. (remm) + </fix> </changelog> </subsection> <subsection name="Coyote">
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
15- github.com/advisories/GHSA-83qj-6fr2-vhqgghsaADVISORY
- lists.apache.org/thread/j5fkjv2k477os90nczf2v9l61fb0kkgqghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2025-24813ghsaADVISORY
- www.openwall.com/lists/oss-security/2025/03/10/5ghsaWEB
- github.com/absholi7ly/POC-CVE-2025-24813/blob/main/README.mdghsaWEB
- github.com/apache/tomcat/commit/0a668e0c27f2b7ca0cc7c6eea32253b9b5ecb29cghsaWEB
- github.com/apache/tomcat/commit/eb61aade8f8daccaecabf07d428b877975622f72ghsaWEB
- github.com/apache/tomcat/commit/f6c01d6577cf9a1e06792be47e623d36acc3b5dcghsaWEB
- lists.debian.org/debian-lts-announce/2025/04/msg00003.htmlghsaWEB
- security.netapp.com/advisory/ntap-20250321-0001ghsaWEB
- www.cisa.gov/known-exploited-vulnerabilities-catalogghsaWEB
- www.vicarius.io/vsociety/posts/cve-2025-24813-detect-apache-tomcat-rceghsaWEB
- www.vicarius.io/vsociety/posts/cve-2025-24813-mitigate-apache-tomcat-rceghsaWEB
- www.vicarius.io/vsociety/posts/cve-2025-24813-tomcat-detect-vulnerabilityghsaWEB
- www.vicarius.io/vsociety/posts/cve-2025-24813-tomcat-mitigation-vulnerabilityghsaWEB
News mentions
0No linked articles in our index yet.