SNI hostname and HTTP Host can drift, with no visibility
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
Kestrel selects the TLS profile from the ClientHello SNI (`SniOptionsSelector.OptionsCallback`, `src/Servers/Kestrel/Core/src/Internal/SniOptionsSelector.cs:179`), while HTTP-layer host authorization is performed independently against the `Host` header in `HostFilteringMiddleware` (`src/Middleware/HostFiltering/src/HostFilteringMiddleware.cs:82`). A client can legitimately pair any SNI with any `Host`, so the TLS policy applied to the connection and the host the request is routed to can diverge.
This is allowed by RFC 6066 §3 ("MAY use ... to guide its selection of ... security policy") and is required by scenarios like TLS-terminating proxies and connection reuse, so enforcing equality is not desirable. However, today there is no built-in way for an application to observe or enforce alignment when it wants to.
### Proposed fix (non-breaking)
Expose the SNI hostname used for TLS selection on a connection feature (e.g. extend `ITlsHandshakeFeature` or add `ISniHostnameFeature`) so middleware and auth handlers can compare it against `HttpContext.Request.Host` when their policy calls for it. Optionally add an opt-in Kestrel/HostFiltering option to reject requests whose `Host` does not fall under the matched SNI entry.
### Why
Apps that layer stricter TLS policy (mTLS, TLS 1.3-only, custom cipher policy) on specific SNI entries currently have no first-class way to detect when a request arrived under a different SNI than its `Host` claims. Making the SNI value observable lets applications add that check where their threat model requires it, without breaking legitimate SNI/Host mismatches.
Related #67721
Contributor guide
Research direction
Start by reading SniOptionsSelector.OptionsCallback in src/Servers/Kestrel/Core/src/Internal/SniOptionsSelector.cs and host authorization in src/Middleware/HostFiltering/src/HostFilteringMiddleware.cs. Determine a non-breaking way to expose the selected SNI hostname for comparison with HttpContext.Request.Host, and define coverage for the observable value and any opt-in rejection behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100