Skip to content

Validate realm returned in the container auth handshake#54225

Merged
mthalman merged 5 commits into
dotnet:mainfrom
mthalman:container-auth
May 12, 2026
Merged

Validate realm returned in the container auth handshake#54225
mthalman merged 5 commits into
dotnet:mainfrom
mthalman:container-auth

Conversation

@mthalman
Copy link
Copy Markdown
Member

@mthalman mthalman commented May 7, 2026

When a container registry returns a 401 Unauthorized with a bearer challenge, AuthHandshakeMessageHandler previously used the realm URL as-is to fetch a bearer token. Because that URL is supplied by the registry response, the handler effectively trusted any value the registry put there - including malformed or malicious URLs.

This change adds a ValidateRealmUri method that validates the realm before using it in in a subsequent request. The validator rejects the realm if any of the following are true:

  • It does not parse as an absolute URI, or its scheme is anything other than https (or http, but only when the registry is configured as insecure).
  • It is an IP literal in a reserved range: loopback, unspecified, private, link-local.
  • It is a Unicode-dot form that Uri.IdnHost canonicalizes back to a blocked IPv4 literal (i.e., what the runtime would actually connect to).

Why not just require the realm host to equal the registry host? Because it would break authentication against essentially every major public registry. This host-separation pattern is the normal shape of OCI bearer auth, not an edge case. For example, Docker Hub's registry (registry-1.docker.io) uses auth.docker.io for its bearer realm.

Why an exception for matching IP literals when the registry is insecure? Private/on-prem dev registries routinely return a realm whose host equals the registry host. Rejecting that would break that dev workflow. The exception is narrowly scoped: the realm host must match the registry host, and the insecure registry flag must already have been set, meaning the operator has explicitly opted in to talking to that registry over an insecure channel.

Copilot AI review requested due to automatic review settings May 7, 2026 16:32
@mthalman mthalman requested a review from a team as a code owner May 7, 2026 16:32
@github-actions github-actions Bot added the Area-Containers Related to dotnet SDK containers functionality label May 7, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens container registry Bearer authentication by validating the realm URI returned in WWW-Authenticate challenges before using it for a token request, reducing the chance of credential exfiltration/SSRF via malicious or malformed realm values.

Changes:

  • Add realm URI validation (scheme allowlist + blocked IP-literal ranges + IDN/unicode-dot canonicalization hardening) and plumb the validated URI into token/OAuth flows.
  • Introduce InvalidAuthResponseException plus new localized strings for clearer failures when registries return unsafe auth challenges.
  • Expand unit tests to cover validation edge cases and an end-to-end “don’t follow malicious realm” scenario.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs Adds unit and end-to-end coverage for realm validation, and updates handler construction for new isInsecureRegistry parameter.
src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs Adds ValidateRealmUri and blocked-network logic; passes validated realm into token/OAuth requests; extends handler ctor to include isInsecureRegistry.
src/Containers/Microsoft.NET.Build.Containers/Exceptions/InvalidAuthResponseException.cs Adds a dedicated exception type for invalid/malicious registry auth responses.
src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultRegistryAPI.cs Wires isInsecureRegistry into AuthHandshakeMessageHandler construction.
src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx Adds new resource strings for invalid auth response reporting.
src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs Regenerates strongly-typed accessors for the new resource strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf Adds new trans-units for auth-response validation strings.
src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf Adds new trans-units for auth-response validation strings.
Files not reviewed (1)
  • src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs: Language not supported

Comment thread test/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs Outdated
Copy link
Copy Markdown
Member

@baronfel baronfel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no notes - this is a beautiful PR. Thanks for the thorough documentation on the new APIs, and the comprehensive test suite showing the behaviors.

When this merges/backports we'll need to go update the docs on MS Learn, so I added the documentation label as a reminder.

@mthalman mthalman merged commit e9522f8 into dotnet:main May 12, 2026
24 checks passed
@mthalman mthalman deleted the container-auth branch May 12, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Containers Related to dotnet SDK containers functionality Document for new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants