Reject ambiguous NuGet credential routes - #206
Conversation
|
I don't recommend rejecting requests to the ambiguous URLs as I think there is a possible case for the URL collision to happen naturally, but it's not actually a security issue. Short version: when a duplicate NuGet URL is detected, log that it is being ignored because it was already registered, but do not prevent requests to it. High level overview of NuGetThis high level overview of NuGet is overly simplified and in some cases wrong, but it's enough to understand the issues here. A NuGet feed is specified by a URL like Accidental conflictIt's plausible for two different NuGet feeds to report the same An Azure DevOps feed can look like this: Given that the initial Engineered conflict
|
|
I added the suggested log line about ignoring duplicate URLs to: |
Summary
This is a security-policy discussion draft stacked on #203. It changes how the proxy handles the same normalized NuGet route being claimed by multiple configured service indexes.
Today, the first service-index response to register a discovered route supplies its credential. When different indexes claim the same route with different credentials, response timing can therefore decide which credential is injected. Deterministic selection would remove timing variance but would not establish that the selected credential is authorized for the shared route.
Proposed policy
token: "user:password"is equivalent to matchingusername/passwordfields.What this does not reject
Two feeds or mirrors may offer the same package ID/version at different resource URLs. Those routes remain independent and each receives its own credential. The proxy does not attempt to compare package contents or decide NuGet source precedence.
For example, this remains valid:
Only an exact normalized route claim is considered ambiguous:
Implementation notes
A claim table is seeded for configured service-index URLs and extended for authenticated redirects and discovered resource URLs. The conflict check runs before every NuGet OIDC, static URL, and host-only lookup. The first credential may remain stored in an underlying registry, but it is unreachable for a conflicted route while the deny guard is active.
The current draft conservatively blocks NuGet credential injection for descendants of a conflicting route, even if a separately configured route is more specific. That favors fail-closed behavior but is an explicit point for review.
Questions for review
401/403preferable to failing the request directly in the proxy?Validation
go test -race ./internal/handlers ./internal/oidc -count=1passes.Stack