From c29ba3e5eeb51ee0a3f2fbda3f2261605babb18d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 30 Aug 2021 16:33:29 +1000 Subject: [PATCH] Alternate fix for #6497 Signed-off-by: Greg Wilkins --- .../server/AllowedResourceAliasChecker.java | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AllowedResourceAliasChecker.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AllowedResourceAliasChecker.java index 5132c94ba048..734a1b357724 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AllowedResourceAliasChecker.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AllowedResourceAliasChecker.java @@ -21,6 +21,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; @@ -100,6 +102,7 @@ public boolean check(String pathInContext, Resource resource) Path link = path.toRealPath(NO_FOLLOW_LINKS); Path real = path.toRealPath(FOLLOW_LINKS); + // Allowed IFF the real file is allowed and either it is not linked or the link file itself is also allowed. return isAllowed(real) && (link.equals(real) || isAllowed(link)); } catch (Throwable t) @@ -114,19 +117,22 @@ protected boolean isAllowed(Path path) throws IOException // If the resource doesn't exist we cannot determine whether it is protected so we assume it is. if (Files.exists(path)) { + // resolve the protected paths now, as they may have changed since start + List protect = _protected.stream() + .map(AllowedResourceAliasChecker::getRealPath) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // Walk the path parent links looking for the base resource, but failing if any steps are protected while (path != null) { if (Files.isSameFile(path, _base)) return true; - for (Path protectedPath : _protected) + for (Path p : protect) { - if (Files.exists(protectedPath)) - { - protectedPath = protectedPath.toRealPath(FOLLOW_LINKS); - if (Files.exists(protectedPath) && Files.isSameFile(path, protectedPath)) - return false; - } + if (Files.isSameFile(path, p)) + return false; } path = path.getParent(); @@ -136,6 +142,24 @@ protected boolean isAllowed(Path path) throws IOException return false; } + private static Path getRealPath(Path path) + { + if (path == null || !Files.exists(path)) + return null; + try + { + path = path.toRealPath(FOLLOW_LINKS); + if (Files.exists(path)) + return path; + } + catch (IOException e) + { + if (LOG.isDebugEnabled()) + LOG.debug("No real path for {}", path, e); + } + return null; + } + protected Path getPath(Resource resource) { try @@ -160,4 +184,4 @@ public String toString() _base, Arrays.asList(_contextHandler.getProtectedTargets())); } -} \ No newline at end of file +}