// Copyright 2025 Envoy Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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.
//
// The validator performs comprehensive HTTP header validation including:
//
// #. 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>`_.
//
// This validator ensures that HTTP traffic processed by Envoy conforms to established
// standards and helps prevent issues caused by malformed headers or invalid HTTP syntax.
//
// [#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 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.
  //
  // This setting provides control over how to handle such headers for security and compatibility reasons.
  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;
  }

  // Configuration options for URI path normalization and transformation.
  //
  // These options control how Envoy processes and normalizes incoming request URI paths
  // to ensure consistent behavior and security. Path normalization helps prevent
  // path traversal attacks and ensures that equivalent paths are handled consistently.
  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.
    //
    // Escaped slash sequences in URLs can be used for path confusion attacks, so proper handling
    // is important for security.
    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 unchanged in the URI path.
      // This preserves the original request path without any modifications to escaped sequences.
      KEEP_UNCHANGED = 1;

      // Reject client request with the 400 status. gRPC requests will be rejected with the ``INTERNAL`` (13) error code.
      // The :ref:`httpN.downstream_rq_failed_path_normalization <config_http_conn_man_stats_per_codec>` counter is incremented for each rejected request.
      //
      // This is the safest option when security is a primary concern, as it prevents any potential
      // path confusion attacks by rejecting requests with escaped slashes entirely.
      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 :ref:`httpN.downstream_rq_redirected_with_normalized_path <config_http_conn_man_stats_per_codec>` counter is incremented for each
      // redirected request.
      UNESCAPE_AND_REDIRECT = 3;

      // Unescape ``%2F`` and ``%5C`` sequences.
      //
      // .. attention::
      //
      //   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::
    //
    //   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::
    //
    //   Slash merging is not part of the
    //   `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.
    //
    // The handling of escaped slashes is important for security as these sequences can be used
    // in path confusion attacks to bypass access controls.
    PathWithEscapedSlashesAction path_with_escaped_slashes_action = 3
        [(validate.rules).enum = {defined_only: true}];
  }

  // HTTP/1 protocol specific options for header validation.
  //
  // These options control how Envoy handles HTTP/1 specific behaviors and edge cases
  // that may not apply to HTTP/2 or HTTP/3 protocols.
  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;
  }

  // HTTP/1 protocol specific options.
  // These settings control HTTP/1 specific validation behaviors.
  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.
  //
  // .. attention::
  //
  //   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.
  //
  // This setting helps enforce HTTP compliance and can prevent attacks that rely on
  // non-standard HTTP methods.
  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``.
  //
  // This setting provides security control over headers with underscores, which can be a source
  // of security issues when different systems interpret underscores and hyphens differently.
  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. When this option is enabled,
  // the fragment portion (everything after ``#``) will be removed from the path before
  // further processing.
  //
  // Fragments are typically used by client-side applications and should not normally
  // be sent to the server, so stripping them can help normalize requests.
  bool strip_fragment_from_path = 5;
}
