diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2022-04-11 11:09:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-11 11:09:26 +0200 |
commit | 23841f2517967c1a59cf9826f1de953c5caa7199 (patch) | |
tree | de8030f99ac0901aa3e6911e0d54c4feaf592118 | |
parent | 11c97272cdc0459ee4b409d7cccb8f38ad908276 (diff) | |
parent | 016161433518cf30d3893f4d3b97f15e628bca3e (diff) |
Merge pull request #22079 from vespa-engine/jonmv/avoid-segment-validation-in-rule-filter
Avoid segment validation in rule based filter
4 files changed, 10 insertions, 4 deletions
diff --git a/container-core/src/main/java/com/yahoo/restapi/Path.java b/container-core/src/main/java/com/yahoo/restapi/Path.java index 80f9391fb56..01bcb627639 100644 --- a/container-core/src/main/java/com/yahoo/restapi/Path.java +++ b/container-core/src/main/java/com/yahoo/restapi/Path.java @@ -46,6 +46,11 @@ public class Path { this.path = HttpURL.Path.parse(uri.getRawPath(), validator); } + /** Create a new Path for matching the given URI against patterns, without any segment validation. */ + public static Path withoutValidation(URI uri) { + return new Path(uri, __ -> { }); + } + private boolean matchesInner(String pathSpec) { values.clear(); List<String> specElements = HttpURL.Path.parse(pathSpec).segments(); diff --git a/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilter.java b/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilter.java index fb384a3f980..c5ec08e23cb 100644 --- a/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilter.java +++ b/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilter.java @@ -118,8 +118,9 @@ public class RuleBasedRequestFilter extends JsonSecurityRequestFilterBase { boolean methodMatches = methods.isEmpty() || methods.contains(method.toUpperCase()); String host = uri.getHost(); boolean hostnameMatches = hostnames.isEmpty() || (host != null && hostnames.contains(host)); - Path pathMatcher = new Path(uri); - boolean pathMatches = pathGlobExpressions.isEmpty() || pathGlobExpressions.stream().anyMatch(pathMatcher::matches); + // Path segments cannot be validated in this filter, as we don't know what API it protects. + // Specifically, /document/v1 must allow _any_ rest path segment, as there is no restriction on document IDs. + boolean pathMatches = pathGlobExpressions.isEmpty() || pathGlobExpressions.stream().anyMatch(Path.withoutValidation(uri)::matches); return methodMatches && hostnameMatches && pathMatches; } diff --git a/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java b/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java index c4171ecd4d7..cfd0e80968f 100644 --- a/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java +++ b/jdisc-security-filters/src/test/java/com/yahoo/jdisc/http/filter/security/rule/RuleBasedRequestFilterTest.java @@ -51,7 +51,7 @@ class RuleBasedRequestFilterTest { Metric metric = mock(Metric.class); RuleBasedRequestFilter filter = new RuleBasedRequestFilter(metric, config); MockResponseHandler responseHandler = new MockResponseHandler(); - filter.filter(request("PATCH", "http://myserver:80/path-to-resource"), responseHandler); + filter.filter(request("PATCH", "http://myserver:80/path-to-resource%2F"), responseHandler); assertAllowed(responseHandler, metric); diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java index 29c572422c3..9ec25f8b6a6 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java @@ -236,7 +236,7 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler { + handlerTimeout.toMillis(), MILLISECONDS); - Path requestPath = new Path(request.getUri(), __ -> { }); // No segment validation here, as document IDs can be anything. + Path requestPath = Path.withoutValidation(request.getUri()); // No segment validation here, as document IDs can be anything. for (String path : handlers.keySet()) if (requestPath.matches(path)) { Map<Method, Handler> methods = handlers.get(path); |