syntax = "proto3";

package envoy.extensions.http.header_validators.envoy_default.v3;

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.http.header_validators.envoy_default.v3";
option java_outer_classname = "HeaderValidatorProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/header_validators/envoy_default/v3;envoy_defaultv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Envoy's default Header Validator config]

// This extension validates that HTTP request and response headers are well formed according to respective RFCs.
//
// #. HTTP/1 header map validity according to `RFC 7230 section 3.2 <https://datatracker.ietf.org/doc/html/rfc7230#section-3.2>`_
// #. Syntax of HTTP/1 request target URI and response status
// #. HTTP/2 header map validity according to `RFC 7540 section 8.1.2 <https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2>`_
// #. Syntax of HTTP/2 pseudo headers
// #. HTTP/3 header map validity according to `RFC 9114 section 4.3  <https://www.rfc-editor.org/rfc/rfc9114.html>`_
// #. Syntax of HTTP/3 pseudo headers
// #. Syntax of Content-Length and Transfer-Encoding
// #. Validation of HTTP/1 requests with both ``Content-Length`` and ``Transfer-Encoding`` headers
// #. Normalization of the URI path according to `Normalization and Comparison <https://datatracker.ietf.org/doc/html/rfc3986#section-6>`_
//    without `case normalization <https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1>`_
//
// [#comment:TODO(yanavlasov): Put #extension: envoy.http.header_validators.envoy_default after it is not hidden any more]
// [#next-free-field: 6]
message HeaderValidatorConfig {
  // Action to take when Envoy receives client request with header names containing underscore
  // characters.
  // Underscore character is allowed in header names by the RFC-7230 and this behavior is implemented
  // as a security measure due to systems that treat '_' and '-' as interchangeable. Envoy by default allows client request headers with underscore
  // characters.
  enum HeadersWithUnderscoresAction {
    // Allow headers with underscores. This is the default behavior.
    ALLOW = 0;

    // Reject client request. HTTP/1 requests are rejected with the 400 status. HTTP/2 requests
    // end with the stream reset. The
    // :ref:`httpN.requests_rejected_with_underscores_in_headers <config_http_conn_man_stats_per_codec>` counter
    // is incremented for each rejected request.
    REJECT_REQUEST = 1;

    // Drop the client header with name containing underscores. The header is dropped before the filter chain is
    // invoked and as such filters will not see dropped headers. The
    // :ref:`httpN.dropped_headers_with_underscores <config_http_conn_man_stats_per_codec>` is incremented for
    // each dropped header.
    DROP_HEADER = 2;
  }

  message UriPathNormalizationOptions {
    // Determines the action for requests that contain ``%2F``, ``%2f``, ``%5C`` or ``%5c`` sequences in the URI path.
    // This operation occurs before URL normalization and the merge slashes transformations if they were enabled.
    enum PathWithEscapedSlashesAction {
      // Default behavior specific to implementation (i.e. Envoy) of this configuration option.
      // Envoy, by default, takes the ``KEEP_UNCHANGED`` action.
      // NOTE: the implementation may change the default behavior at-will.
      IMPLEMENTATION_SPECIFIC_DEFAULT = 0;

      // Keep escaped slashes.
      KEEP_UNCHANGED = 1;

      // Reject client request with the 400 status. gRPC requests will be rejected with the ``INTERNAL`` (13) error code.
      // The ``http#.downstream_rq_failed_path_normalization`` counter is incremented for each rejected request.
      REJECT_REQUEST = 2;

      // Unescape ``%2F`` and ``%5C`` sequences and redirect the request to the new path if these sequences were present.
      // The redirect occurs after path normalization and merge slashes transformations if they were configured.
      // NOTE: gRPC requests will be rejected with the ``INTERNAL`` (13) error code.
      // This option minimizes possibility of path confusion exploits by forcing request with unescaped slashes to
      // traverse all parties: downstream client, intermediate proxies, Envoy and upstream server.
      // The ``http#.downstream_rq_redirected_with_normalized_path`` counter is incremented for each
      // redirected request.
      UNESCAPE_AND_REDIRECT = 3;

      // Unescape ``%2F`` and ``%5C`` sequences.
      // Note: this option should not be enabled if intermediaries perform path based access control as
      // it may lead to path confusion vulnerabilities.
      UNESCAPE_AND_FORWARD = 4;
    }

    // Should paths be normalized according to RFC 3986?
    // This operation overwrites the original request URI path and the new path is used for processing of
    // the request by HTTP filters and proxied to the upstream service.
    // Envoy will respond with 400 to requests with malformed paths that fail path normalization.
    // The default behavior is to normalize the path.
    // This value may be overridden by the runtime variable
    // :ref:`http_connection_manager.normalize_path<config_http_conn_man_runtime_normalize_path>`.
    // See `Normalization and Comparison <https://datatracker.ietf.org/doc/html/rfc3986#section-6>`_
    // for details of normalization.
    // Note that Envoy does not perform
    // `case normalization <https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1>`_
    // URI path normalization can be applied to a portion of requests by setting the
    // ``envoy_default_header_validator.path_normalization`` runtime value.
    bool skip_path_normalization = 1;

    // Determines if adjacent slashes in the path are merged into one.
    // This operation overwrites the original request URI path and the new path is used for processing of
    // the request by HTTP filters and proxied to the upstream service.
    // Setting this option to true will cause incoming requests with path ``//dir///file`` to not match against
    // route with ``prefix`` match set to ``/dir``. Defaults to ``false``. Note that slash merging is not part of
    // `HTTP spec <https://datatracker.ietf.org/doc/html/rfc3986>`_ and is provided for convenience.
    // Merging of slashes in URI path can be applied to a portion of requests by setting the
    // ``envoy_default_header_validator.merge_slashes`` runtime value.
    bool skip_merging_slashes = 2;

    // The action to take when request URL path contains escaped slash sequences (``%2F``, ``%2f``, ``%5C`` and ``%5c``).
    // This operation may overwrite the original request URI path and the new path is used for processing of
    // the request by HTTP filters and proxied to the upstream service.
    PathWithEscapedSlashesAction path_with_escaped_slashes_action = 3
        [(validate.rules).enum = {defined_only: true}];
  }

  message Http1ProtocolOptions {
    // Allows Envoy to process HTTP/1 requests/responses with both ``Content-Length`` and ``Transfer-Encoding``
    // headers set. By default such messages are rejected, but if option is enabled - Envoy will
    // remove the ``Content-Length`` header and process the message.
    // See `RFC7230, sec. 3.3.3 <https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3>`_ for details.
    //
    // .. attention::
    //   Enabling this option might lead to request smuggling vulnerabilities, especially if traffic
    //   is proxied via multiple layers of proxies.
    bool allow_chunked_length = 1;
  }

  Http1ProtocolOptions http1_protocol_options = 1;

  // The URI path normalization options.
  // By default Envoy normalizes URI path using the default values of the :ref:`UriPathNormalizationOptions
  // <envoy_v3_api_msg_extensions.http.header_validators.envoy_default.v3.HeaderValidatorConfig.UriPathNormalizationOptions>`.
  // URI path transformations specified by the ``uri_path_normalization_options`` configuration can be applied to a portion
  // of requests by setting the ``envoy_default_header_validator.uri_path_transformations`` runtime value.
  // Caution: disabling path normalization may lead to path confusion vulnerabilities in access control or incorrect service
  // selection.
  UriPathNormalizationOptions uri_path_normalization_options = 2;

  // Restrict HTTP methods to these defined in the `RFC 7231 section 4.1 <https://datatracker.ietf.org/doc/html/rfc7231#section-4.1>`_
  // Envoy will respond with 400 to requests with disallowed methods.
  // By default methods with arbitrary names are accepted.
  bool restrict_http_methods = 3;

  // Action to take when a client request with a header name containing underscore characters is received.
  // If this setting is not specified, the value defaults to ALLOW.
  HeadersWithUnderscoresAction headers_with_underscores_action = 4;

  // Allow requests with fragment in URL path and strip the fragment before request processing.
  // By default Envoy rejects requests with fragment in URL path.
  bool strip_fragment_from_path = 5;
}
