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();
+ }
+ }
}