Kestrel SNI configuration does not canonicalize IDN host names
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
I have searched the existing issues.
### Describe the bug
Kestrel stores configured SNI names verbatim, but `System.Net.Security` exposes internationalized server names to Kestrel in Unicode form.
For example, a configuration entry named `secure.xn--mnchen-3ya.example` does not match the equivalent server name received by `SniOptionsSelector`, `secure.münchen.example`. Consequently, the exact-name lookup misses and Kestrel either selects the `*` fallback configuration or rejects the connection when no fallback exists. Wildcard suffix entries containing IDN A-labels are affected similarly.
This can cause the wrong configured certificate, protocols, or other per-SNI options to be selected.
### Expected Behavior
Equivalent IDNA A-label and Unicode representations should select the same SNI configuration entry. An exact IDN match should take precedence over wildcard entries regardless of which representation was used in configuration.
### Steps To Reproduce
Configure an endpoint with distinct certificates for an IDN A-label and the fallback:
```json
"Sni": {
"secure.xn--mnchen-3ya.example": {
"Certificate": {
"Path": "idn.pfx"
}
},
"*": {
"Certificate": {
"Path": "fallback.pfx"
}
}
}
```
Connect using:
```console
openssl s_client -connect localhost:5001 -servername secure.xn--mnchen-3ya.example
```
The fallback certificate is selected. Changing the configuration key to `secure.münchen.example` selects the intended certificate.
### Exceptions (if any)
Without a `*` fallback entry, the TLS connection is rejected because no SNI configuration matches.
### .NET Version
10.0.11
### Anything else?
**Workaround:** Configure IDN SNI entries using their Unicode representation rather than the equivalent Punycode A-label. For example, use `secure.münchen.example` instead of `secure.xn--mnchen-3ya.example`.
The relevant lookup is in `src/Servers/Kestrel/Core/src/Internal/SniOptionsSelector.cs`. A possible fix is to canonicalize configured exact names and wildcard suffixes to the same IDNA representation used by `ClientHelloInfo.ServerName` before constructing the lookup collections. The implementation should preserve wildcard syntax and handle configurations containing equivalent A-label and Unicode keys deterministically.
Related: #67721, #67722, #68015.
Contributor guide
Research direction
Read src/Servers/Kestrel/Core/src/Internal/SniOptionsSelector.cs and trace how ClientHelloInfo.ServerName is matched against configured SNI names. Run the provided openssl s_client reproduction with the A-label and Unicode configurations. Done means equivalent IDNA forms select the exact entry before the wildcard, including wildcard suffixes, without rejecting the connection when a matching entry exists.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100