From 1b4624fe0f109bcc5d7a52afa1a8026b2dd6ccae Mon Sep 17 00:00:00 2001 From: "data-plane-api(CircleCI)" Date: Mon, 20 Apr 2020 01:23:23 +0000 Subject: [PATCH] [api] fuzz: add validations matching ASSERT(valid) to config fields (#10773) Fuzzing catches more fields tripping on ASSERT(valid()) * JWT Authn filter has HTTP header name/value strings: forward_payload_header, name, value * Route components: request_headers_to_remove * health_check.proto: host, path, authority, and request_headers_to_remove Test-only: * utility fuzz test was running findQueryStringStart on a HeaderString. Fuzz inputs were not validated. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=21323 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=21623 Signed-off-by: Asra Ali Mirrored from https://github.com/envoyproxy/envoy @ 167df8c4554073d5115316ac36dd97088c3e6d93 --- envoy/config/core/v3/health_check.proto | 13 +++++++++---- envoy/config/core/v4alpha/health_check.proto | 13 +++++++++---- envoy/config/route/v3/route_components.proto | 8 ++++++-- envoy/config/route/v4alpha/route_components.proto | 8 ++++++-- .../filters/http/jwt_authn/v3/config.proto | 9 ++++++--- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/envoy/config/core/v3/health_check.proto b/envoy/config/core/v3/health_check.proto index 52dda6f9..f4ef02e0 100644 --- a/envoy/config/core/v3/health_check.proto +++ b/envoy/config/core/v3/health_check.proto @@ -87,11 +87,13 @@ message HealthCheck { // left empty (default value), the name of the cluster this health check is associated // with will be used. The host header can be customized for a specific endpoint by setting the // :ref:`hostname ` field. - string host = 1; + string host = 1 [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; // Specifies the HTTP path that will be requested during health checking. For example // */healthcheck*. - string path = 2 [(validate.rules).string = {min_bytes: 1}]; + string path = 2 [ + (validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_VALUE strict: false} + ]; // [#not-implemented-hide:] HTTP specific payload. Payload send = 3; @@ -108,7 +110,9 @@ message HealthCheck { // Specifies a list of HTTP headers that should be removed from each request that is sent to the // health checked cluster. - repeated string request_headers_to_remove = 8; + repeated string request_headers_to_remove = 8 [(validate.rules).repeated = { + items {string {well_known_regex: HTTP_HEADER_NAME strict: false}} + }]; // Specifies a list of HTTP response statuses considered healthy. If provided, replaces default // 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open @@ -169,7 +173,8 @@ message HealthCheck { // left empty (default value), the name of the cluster this health check is associated // with will be used. The authority header can be customized for a specific endpoint by setting // the :ref:`hostname ` field. - string authority = 2; + string authority = 2 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; } // Custom health check. diff --git a/envoy/config/core/v4alpha/health_check.proto b/envoy/config/core/v4alpha/health_check.proto index 0e6c4e73..1975c309 100644 --- a/envoy/config/core/v4alpha/health_check.proto +++ b/envoy/config/core/v4alpha/health_check.proto @@ -87,11 +87,13 @@ message HealthCheck { // left empty (default value), the name of the cluster this health check is associated // with will be used. The host header can be customized for a specific endpoint by setting the // :ref:`hostname ` field. - string host = 1; + string host = 1 [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; // Specifies the HTTP path that will be requested during health checking. For example // */healthcheck*. - string path = 2 [(validate.rules).string = {min_bytes: 1}]; + string path = 2 [ + (validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_VALUE strict: false} + ]; // [#not-implemented-hide:] HTTP specific payload. Payload send = 3; @@ -108,7 +110,9 @@ message HealthCheck { // Specifies a list of HTTP headers that should be removed from each request that is sent to the // health checked cluster. - repeated string request_headers_to_remove = 8; + repeated string request_headers_to_remove = 8 [(validate.rules).repeated = { + items {string {well_known_regex: HTTP_HEADER_NAME strict: false}} + }]; // Specifies a list of HTTP response statuses considered healthy. If provided, replaces default // 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open @@ -169,7 +173,8 @@ message HealthCheck { // left empty (default value), the name of the cluster this health check is associated // with will be used. The authority header can be customized for a specific endpoint by setting // the :ref:`hostname ` field. - string authority = 2; + string authority = 2 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; } // Custom health check. diff --git a/envoy/config/route/v3/route_components.proto b/envoy/config/route/v3/route_components.proto index f63f0961..70c52010 100644 --- a/envoy/config/route/v3/route_components.proto +++ b/envoy/config/route/v3/route_components.proto @@ -108,7 +108,9 @@ message VirtualHost { // Specifies a list of HTTP headers that should be removed from each request // handled by this virtual host. - repeated string request_headers_to_remove = 13; + repeated string request_headers_to_remove = 13 [(validate.rules).repeated = { + items {string {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}} + }]; // Specifies a list of HTTP headers that should be added to each response // handled by this virtual host. Headers specified at this level are applied @@ -252,7 +254,9 @@ message Route { // Specifies a list of HTTP headers that should be removed from each request // matching this route. - repeated string request_headers_to_remove = 12; + repeated string request_headers_to_remove = 12 [(validate.rules).repeated = { + items {string {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}} + }]; // Specifies a set of headers that will be added to responses to requests // matching this route. Headers specified at this level are applied before diff --git a/envoy/config/route/v4alpha/route_components.proto b/envoy/config/route/v4alpha/route_components.proto index 33f8d645..e813b632 100644 --- a/envoy/config/route/v4alpha/route_components.proto +++ b/envoy/config/route/v4alpha/route_components.proto @@ -108,7 +108,9 @@ message VirtualHost { // Specifies a list of HTTP headers that should be removed from each request // handled by this virtual host. - repeated string request_headers_to_remove = 13; + repeated string request_headers_to_remove = 13 [(validate.rules).repeated = { + items {string {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}} + }]; // Specifies a list of HTTP headers that should be added to each response // handled by this virtual host. Headers specified at this level are applied @@ -252,7 +254,9 @@ message Route { // Specifies a list of HTTP headers that should be removed from each request // matching this route. - repeated string request_headers_to_remove = 12; + repeated string request_headers_to_remove = 12 [(validate.rules).repeated = { + items {string {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}} + }]; // Specifies a set of headers that will be added to responses to requests // matching this route. Headers specified at this level are applied before diff --git a/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/envoy/extensions/filters/http/jwt_authn/v3/config.proto index 1aabe1bd..39fe6187 100644 --- a/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -171,7 +171,8 @@ message JwtProvider { // base64url_encoded(jwt_payload_in_JSON) // // If it is not specified, the payload will not be forwarded. - string forward_payload_header = 8; + string forward_payload_header = 8 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false}]; // If non empty, successfully verified JWT payloads will be written to StreamInfo DynamicMetadata // in the format as: *namespace* is the jwt_authn filter name as **envoy.filters.http.jwt_authn** @@ -218,12 +219,14 @@ message JwtHeader { "envoy.config.filter.http.jwt_authn.v2alpha.JwtHeader"; // The HTTP header name. - string name = 1 [(validate.rules).string = {min_bytes: 1}]; + string name = 1 + [(validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; // The value prefix. The value format is "value_prefix" // For example, for "Authorization: Bearer ", value_prefix="Bearer " with a space at the // end. - string value_prefix = 2; + string value_prefix = 2 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; } // Specify a required provider with audiences.