File tomcat-9.0.36-CVE-2025-49125.patch of Package tomcat.39434
From 9418e3ff9f1f4c006b4661311ae9376c52d162b9 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Wed, 4 Jun 2025 11:28:24 +0100
Subject: [PATCH] Expand checks for webAppMount
---
Index: apache-tomcat-9.0.36-src/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
===================================================================
--- apache-tomcat-9.0.36-src.orig/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
+++ apache-tomcat-9.0.36-src/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
@@ -68,7 +68,7 @@ public abstract class AbstractArchiveRes
String webAppMount = getWebAppMount();
ArrayList<String> result = new ArrayList<>();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
String pathInJar =
getInternalPath() + path.substring(webAppMount.length());
// Always strip off the leading '/' to get the JAR path
@@ -118,7 +118,7 @@ public abstract class AbstractArchiveRes
String webAppMount = getWebAppMount();
ResourceSet<String> result = new ResourceSet<>();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
String pathInJar =
getInternalPath() + path.substring(webAppMount.length());
// Always strip off the leading '/' to get the JAR path and make
@@ -229,7 +229,7 @@ public abstract class AbstractArchiveRes
// If the JAR has been mounted below the web application root, return
// an empty resource for requests outside of the mount point.
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
String pathInJar = getInternalPath() + path.substring(
webAppMount.length(), path.length());
// Always strip off the leading '/' to get the JAR path
Index: apache-tomcat-9.0.36-src/java/org/apache/catalina/webresources/AbstractResourceSet.java
===================================================================
--- apache-tomcat-9.0.36-src.orig/java/org/apache/catalina/webresources/AbstractResourceSet.java
+++ apache-tomcat-9.0.36-src/java/org/apache/catalina/webresources/AbstractResourceSet.java
@@ -85,6 +85,18 @@ public abstract class AbstractResourceSe
return webAppMount;
}
+ protected boolean isPathMounted(String path, String webAppMount) {
+ // Doesn't call getWebAppMount() as value might have changed
+ if (path.startsWith(webAppMount)) {
+ if (path.length() != webAppMount.length() && path.charAt(webAppMount.length()) != '/') {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+
public final void setBase(String base) {
this.base = base;
}
Index: apache-tomcat-9.0.36-src/test/org/apache/catalina/webresources/AbstractTestResourceSet.java
===================================================================
--- apache-tomcat-9.0.36-src.orig/test/org/apache/catalina/webresources/AbstractTestResourceSet.java
+++ apache-tomcat-9.0.36-src/test/org/apache/catalina/webresources/AbstractTestResourceSet.java
@@ -97,7 +97,7 @@ public abstract class AbstractTestResour
}
@Test
- public final void testGetResourceDirA() {
+ public final void testGetResourceDirWithoutTrailingFileSeperator() {
WebResource webResource = resourceRoot.getResource(getMount() + "/d1");
Assert.assertTrue(webResource.isDirectory());
Assert.assertEquals("d1", webResource.getName());
@@ -108,7 +108,7 @@ public abstract class AbstractTestResour
}
@Test
- public final void testGetResourceDirB() {
+ public final void testGetResourceDirWithTrailingFileSeperator() {
WebResource webResource = resourceRoot.getResource(getMount() + "/d1/");
Assert.assertTrue(webResource.isDirectory());
Assert.assertEquals("d1", webResource.getName());
@@ -119,6 +119,18 @@ public abstract class AbstractTestResour
}
@Test
+ public final void testGetResourceDirWithoutLeadingFileSeperator() {
+ String mount = getMount();
+ if (mount.isEmpty()) {
+ // Test is only meaningful when resource is mounted below web application root.
+ return;
+ }
+ WebResource webResource = resourceRoot.getResource(mount + "d1");
+ Assert.assertFalse(webResource.exists());
+ Assert.assertEquals(mount + "d1", webResource.getWebappPath());
+ }
+
+ @Test
public final void testGetResourceFile() {
WebResource webResource =
resourceRoot.getResource(getMount() + "/d1/d1-f1.txt");
Index: apache-tomcat-9.0.36-src/webapps/docs/changelog.xml
===================================================================
--- apache-tomcat-9.0.36-src.orig/webapps/docs/changelog.xml
+++ apache-tomcat-9.0.36-src/webapps/docs/changelog.xml
@@ -143,6 +143,10 @@
Refactor GCI servlet to access resources via the
<code>WebResource</code> API. (markt)
</scode>
+ <fix>
+ Expand the path checks for Pre-Resources and Post-Resources mounted at a
+ path within the web application. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
Index: apache-tomcat-9.0.36-src/java/org/apache/catalina/webresources/DirResourceSet.java
===================================================================
--- apache-tomcat-9.0.36-src.orig/java/org/apache/catalina/webresources/DirResourceSet.java
+++ apache-tomcat-9.0.36-src/java/org/apache/catalina/webresources/DirResourceSet.java
@@ -109,7 +109,7 @@ public class DirResourceSet extends Abst
checkPath(path);
String webAppMount = getWebAppMount();
WebResourceRoot root = getRoot();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
/*
* Lock the path for reading until the WebResource has been constructed. The lock prevents concurrent reads
* and writes (e.g. HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource
@@ -141,7 +141,7 @@ public class DirResourceSet extends Abst
public String[] list(String path) {
checkPath(path);
String webAppMount = getWebAppMount();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
File f = file(path.substring(webAppMount.length()), true);
if (f == null) {
return EMPTY_STRING_ARRAY;
@@ -174,7 +174,7 @@ public class DirResourceSet extends Abst
checkPath(path);
String webAppMount = getWebAppMount();
ResourceSet<String> result = new ResourceSet<>();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
File f = file(path.substring(webAppMount.length()), true);
if (f != null) {
File[] list = f.listFiles();
@@ -216,7 +216,7 @@ public class DirResourceSet extends Abst
return false;
}
String webAppMount = getWebAppMount();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
File f = file(path.substring(webAppMount.length()), false);
if (f == null) {
return false;
@@ -247,7 +247,7 @@ public class DirResourceSet extends Abst
}
String webAppMount = getWebAppMount();
- if (!path.startsWith(webAppMount)) {
+ if (!isPathMounted(path, webAppMount)) {
return false;
}