envoyproxy / envoyproxy/gateway

Consider changing default headers_with_underscores_action to match Envoy proxy

Open
#8,351 12 comments 7 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
3k
Forks
864
Avg merge
2d 2h
Merged PRs (30d)
140

Description

## Context

Envoy Gateway sets `REJECT_REQUEST` as the default for `headers_with_underscores_action` ([listener.go#L1152](https://github.com/envoyproxy/gateway/blob/main/internal/xds/translator/listener.go#L1152)), which differs from Envoy proxy's own default of `ALLOW`.

We understand the intent — this was introduced in #1408 as a security hardening measure against CGI header smuggling. However, underscores are valid in HTTP header names per RFC 9110 (the `tchar` production explicitly includes `_`), and in practice this causes surprising 400 errors for users migrating from other proxies.

## Real-world impact

After migrating a public API gateway from nginx to Envoy Gateway, we discovered a significant volume of requests being rejected due to this default. The underscore headers come from widely-used software and CDNs that operators have no control over:

- **Sentry SDK** — W3C Baggage propagation headers: `ot-baggage-sentry-trace_id`, `ot-baggage-sentry-org_id`, `ot-baggage-sentry-public_key`, `ot-baggage-sentry-sample_rate`, `ot-baggage-sentry-sample_rand`. Any end user whose browser has the Sentry SDK installed will send these headers on API requests.
- **Microsoft IDCRL** — `x-idcrl_accepted`, `x-idcrl_options` (Microsoft authentication protocol headers from crawlers)
- **Fastly CDN** — `backend_is_origin` (Fastly VCL variable forwarded as request header when customers have Fastly in front of your API)
- **OpenTelemetry baggage** — `ot-baggage-query_identifier`, `ot-baggage-client_platform`, `ot-baggage-client_version`
- **Various CDNs and applications** — `dispatch_header`, `cuda_cliip`, `veidemann_jeid`, `veidemann_eid`

## Suggestion

Would it make sense to align with Envoy proxy's default of `ALLOW`? Users who need the CGI protection could opt into `REJECT_REQUEST` or `DROP_HEADER` via ClientTrafficPolicy.

Alternatively, `DROP_HEADER` would be a nice middle ground — it protects backends without returning errors to clients.

## Workaround

Setting `withUnderscoresAction: Allow` in the ClientTrafficPolicy works well. Just noting it here for others who run into this.

## Environment

- Envoy Gateway version: v1.5 (also present in v1.6)
- Envoy proxy default: `ALLOW`

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.