dotnet / dotnet/aspnetcore

Kestrel SNI configuration does not canonicalize IDN host names

Open
#68,938 1 comment 0 reactions 0 assignees View on GitHub
area-networking bug feature-kestrel
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.