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

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


The following commit(s) were added to refs/heads/main by this push:
     new f0702bf07a improve openejb-http resource lookup
f0702bf07a is described below

commit f0702bf07a6517694edad3f5ffbf58824a4a36fd
Author: Markus Jung <[email protected]>
AuthorDate: Sat Aug 29 16:06:07 2026 +0200

    improve openejb-http resource lookup
---
 .../openejb/server/httpd/HttpListenerRegistry.java | 26 ++++++++++++++++++++--
 .../apache/openejb/server/httpd/ResourcesTest.java | 20 +++++++++++++++++
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
index 66f8686160..f1794753d8 100644
--- 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
+++ 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
@@ -192,7 +192,7 @@ public class HttpListenerRegistry implements HttpListener {
             }
             if (!found) {
                 final String servletPath = request.getServletPath();
-                if (servletPath != null) {
+                if (servletPath != null && 
!isForbiddenResourcePath(servletPath)) {
                     URL url = 
SystemInstance.get().getComponent(ServletContext.class).getResource(servletPath);
                     if (url != null) {
                         serveResource(servletPath, response, url);
@@ -205,7 +205,7 @@ public class HttpListenerRegistry implements HttpListener {
                         } else if (resourceBases.length > 0) {
                             for (final File f : resourceBases) {
                                 final File file = new File(f, 
pathWithoutSlash);
-                                if (file.isFile()) {
+                                if (file.isFile() && isContained(f, file)) {
                                     url = file.toURI().toURL();
                                     serveResource(servletPath, response, url);
                                     break;
@@ -240,6 +240,28 @@ public class HttpListenerRegistry implements HttpListener {
         }
     }
 
+    private static boolean isForbiddenResourcePath(final String path) {
+        if (path.indexOf('\0') >= 0 || path.indexOf('\\') >= 0) {
+            return true;
+        }
+        for (final String segment : path.split("/")) {
+            if ("..".equals(segment)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isContained(final File base, final File file) {
+        try {
+            final String basePath = base.getCanonicalPath();
+            final String filePath = file.getCanonicalPath();
+            return filePath.equals(basePath) || filePath.startsWith(basePath + 
File.separator);
+        } catch (final IOException ioe) {
+            return false;
+        }
+    }
+
     private void serveResource(final String key, final HttpResponse response, 
final URL url) throws IOException {
         if (cacheResources) {
             byte[] value = cache.get(key);
diff --git 
a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java
 
b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java
index 0ce1530b5d..f78ceda53a 100644
--- 
a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java
+++ 
b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java
@@ -27,8 +27,11 @@ import org.junit.Rule;
 import org.junit.Test;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
 import java.net.URL;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 @EnableServices("http")
@@ -53,4 +56,21 @@ public class ResourcesTest {
         assertTrue(IO.slurp(new URL(context.toExternalForm() + 
"openejb/bar.txt")).contains("from web"));
         assertTrue(IO.slurp(new URL(context.toExternalForm() + 
"openejb/sub/bar.txt")).contains("from web2"));
     }
+
+    @Test
+    public void parentSegmentsAreNotServed() throws IOException {
+        // src/test/web/../../../pom.xml resolves to the module pom
+        final String body = slurpQuietly(new URL(context.toExternalForm() + 
"openejb/%2e%2e/%2e%2e/%2e%2e/pom.xml"));
+        assertFalse(body, body.contains("<project"));
+    }
+
+    private static String slurpQuietly(final URL url) throws IOException {
+        final HttpURLConnection connection = 
HttpURLConnection.class.cast(url.openConnection());
+        try {
+            final InputStream stream = connection.getResponseCode() < 400 ? 
connection.getInputStream() : connection.getErrorStream();
+            return stream == null ? "" : IO.slurp(stream);
+        } finally {
+            connection.disconnect();
+        }
+    }
 }

Reply via email to