diff options
Diffstat (limited to 'node-repository')
2 files changed, 10 insertions, 0 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/Authorizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/Authorizer.java index 327974599c3..55a1a1e620d 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/Authorizer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/Authorizer.java @@ -54,10 +54,17 @@ public class Authorizer implements BiPredicate<Principal, URI> { /** Returns whether principal can access node identified by hostname */ private boolean canAccess(String hostname, Principal principal) { + // Ignore potential path traversal. Node repository happily passes arguments unsanitized all the way down to + // curator... + if (hostname.chars().allMatch(c -> c == '.')) { + return false; + } + // Node can always access itself if (principal.getName().equals(hostname)) { return true; } + // Parent node can access its children return nodeRepository.getNode(hostname) .flatMap(Node::parentHostname) diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/AuthorizerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/AuthorizerTest.java index 811db071969..097c8d92165 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/AuthorizerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/AuthorizerTest.java @@ -69,6 +69,9 @@ public class AuthorizerTest { assertFalse(authorized("node1", "/nodes/v2/node/node2")); assertFalse(authorized("node1", "/nodes/v2/state/dirty/")); assertFalse(authorized("node1", "/nodes/v2/state/dirty/node2")); + // Path traversal fails gracefully + assertFalse(authorized("node1", "/nodes/v2/node/.")); + assertFalse(authorized("node1", "/nodes/v2/node/..")); assertFalse(authorized("node1", "/nodes/v2/acl/node2")); assertFalse(authorized("node1", "/nodes/v2/node/?parentHost=node2")); // Node resource always takes precedence over filter |