From d4a7391cfa326c401868be72d992f1aec029cc20 Mon Sep 17 00:00:00 2001 From: "data-plane-api(CircleCI)" Date: Fri, 21 Aug 2020 20:34:48 +0000 Subject: [PATCH] header: New HeaderMatcher and StringMatcher type - Contains (#12623) For matching values in the header that might be somewhere in the middle of the header, the present option is to use Regex in the form .Search-Pattern.. This can cause catastrophic backtracking as described in #7728 As a solution, I have introduced another header match type called contains which is based on absl::StrContains(). Risk Level: Low Testing: Unit tests are included and manual testing was performed. Fixes #12590 Signed-off-by: Shivanshu Goswami Mirrored from https://github.com/envoyproxy/envoy @ e322daaf0ca70fd3fcb1c1405830c73395510d93 --- envoy/config/route/v3/route_components.proto | 11 ++++++++++- envoy/config/route/v4alpha/route_components.proto | 11 ++++++++++- envoy/type/matcher/v3/string.proto | 10 +++++++++- envoy/type/matcher/v4alpha/string.proto | 10 +++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/envoy/config/route/v3/route_components.proto b/envoy/config/route/v3/route_components.proto index 857bb3a6..a7882f1d 100644 --- a/envoy/config/route/v3/route_components.proto +++ b/envoy/config/route/v3/route_components.proto @@ -1687,7 +1687,7 @@ message RateLimit { // value. // // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] -// [#next-free-field: 12] +// [#next-free-field: 13] message HeaderMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.HeaderMatcher"; @@ -1741,6 +1741,15 @@ message HeaderMatcher { // // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. string suffix_match = 10 [(validate.rules).string = {min_bytes: 1}]; + + // If specified, header match will be performed based on whether the header value contains + // the given value or not. + // Note: empty contains match is not allowed, please use present_match instead. + // + // Examples: + // + // * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. + string contains_match = 12 [(validate.rules).string = {min_bytes: 1}]; } // If specified, the match result will be inverted before checking. Defaults to false. diff --git a/envoy/config/route/v4alpha/route_components.proto b/envoy/config/route/v4alpha/route_components.proto index 3aac37fb..ebb71364 100644 --- a/envoy/config/route/v4alpha/route_components.proto +++ b/envoy/config/route/v4alpha/route_components.proto @@ -1681,7 +1681,7 @@ message RateLimit { // value. // // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] -// [#next-free-field: 12] +// [#next-free-field: 13] message HeaderMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.config.route.v3.HeaderMatcher"; @@ -1736,6 +1736,15 @@ message HeaderMatcher { // // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. string suffix_match = 10 [(validate.rules).string = {min_bytes: 1}]; + + // If specified, header match will be performed based on whether the header value contains + // the given value or not. + // Note: empty contains match is not allowed, please use present_match instead. + // + // Examples: + // + // * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. + string contains_match = 12 [(validate.rules).string = {min_bytes: 1}]; } // If specified, the match result will be inverted before checking. Defaults to false. diff --git a/envoy/type/matcher/v3/string.proto b/envoy/type/matcher/v3/string.proto index 77fe48ac..d453d43d 100644 --- a/envoy/type/matcher/v3/string.proto +++ b/envoy/type/matcher/v3/string.proto @@ -17,7 +17,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: String matcher] // Specifies the way to match a string. -// [#next-free-field: 7] +// [#next-free-field: 8] message StringMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.StringMatcher"; @@ -53,6 +53,14 @@ message StringMatcher { // The input string must match the regular expression specified here. RegexMatcher safe_regex = 5 [(validate.rules).message = {required: true}]; + + // The input string must have the substring specified here. + // Note: empty contains match is not allowed, please use regex instead. + // + // Examples: + // + // * *abc* matches the value *xyz.abc.def* + string contains = 7 [(validate.rules).string = {min_bytes: 1}]; } // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no diff --git a/envoy/type/matcher/v4alpha/string.proto b/envoy/type/matcher/v4alpha/string.proto index 8ce0b12f..fc17946f 100644 --- a/envoy/type/matcher/v4alpha/string.proto +++ b/envoy/type/matcher/v4alpha/string.proto @@ -17,7 +17,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // [#protodoc-title: String matcher] // Specifies the way to match a string. -// [#next-free-field: 7] +// [#next-free-field: 8] message StringMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.v3.StringMatcher"; @@ -54,6 +54,14 @@ message StringMatcher { // The input string must match the regular expression specified here. RegexMatcher safe_regex = 5 [(validate.rules).message = {required: true}]; + + // The input string must have the substring specified here. + // Note: empty contains match is not allowed, please use regex instead. + // + // Examples: + // + // * *abc* matches the value *xyz.abc.def* + string contains = 7 [(validate.rules).string = {min_bytes: 1}]; } // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no