diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java index 55ac974611a..6c68b6728de 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java @@ -310,7 +310,7 @@ public class PathResource extends Resource @Override public boolean isDirectory() { - return Files.isDirectory(getPath(), LinkOption.NOFOLLOW_LINKS); + return Files.isDirectory(getPath()); } @Override diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java index c1c6fd7c1ca..cae05a53dfd 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java @@ -405,7 +405,16 @@ public abstract class Resource implements Iterable boolean noDepth = true; for (Iterator i = children.iterator(); noDepth && i.hasNext(); ) - noDepth = !i.next().isDirectory(); + { + Resource resource = i.next(); + if (resource.isDirectory()) + { + // If the directory is a symlink we do not want to go any deeper. + Path resourcePath = resource.getPath(); + if (resourcePath == null || !Files.isSymbolicLink(resourcePath)) + noDepth = false; + } + } if (noDepth) return children; diff --git a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java index b3ea77bb4ee..24f85ac3e89 100644 --- a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java +++ b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java @@ -27,7 +27,6 @@ import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.eclipse.jetty.toolchain.test.FS; @@ -728,11 +727,6 @@ public class PathResourceTest resource.resolve("foo.txt") }; - List actual = allResources.stream() - .map(Resource::getURI) - .map(URI::toASCIIString) - .toList(); - assertThat(allResources, containsInAnyOrder(expected)); } } diff --git a/jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AliasCheckerSymlinkTest.java b/jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AliasCheckerSymlinkTest.java index 01c40a8b45b..c87274703e6 100644 --- a/jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AliasCheckerSymlinkTest.java +++ b/jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AliasCheckerSymlinkTest.java @@ -253,8 +253,12 @@ public class AliasCheckerSymlinkTest Arguments.of(null, "/symlinkParentDir/webroot/file", HttpStatus.NOT_FOUND_404, null), Arguments.of(null, "/symlinkParentDir/webroot/WEB-INF/web.xml", HttpStatus.NOT_FOUND_404, null), Arguments.of(null, "/symlinkSiblingDir/file", HttpStatus.NOT_FOUND_404, null), - Arguments.of(null, "/webInfSymlink/web.xml", HttpStatus.NOT_FOUND_404, null) - ); + Arguments.of(null, "/webInfSymlink/web.xml", HttpStatus.NOT_FOUND_404, null), + + // We should only be able to list contents of a symlinked directory if the alias checker is installed. + Arguments.of(null, "/symlinkDir", HttpStatus.NOT_FOUND_404, null), + Arguments.of(allowedResource, "/symlinkDir", HttpStatus.OK_200, null) + ); } public static Stream combinedResourceTestCases()