Skip to content

Guard OIDC discovery against private IPs - #6455

Merged
jhrozek merged 1 commit into
stacklok:mainfrom
jhrozek:ssrf-fix
Aug 29, 2026
Merged

Guard OIDC discovery against private IPs#6455
jhrozek merged 1 commit into
stacklok:mainfrom
jhrozek:ssrf-fix

Conversation

@jhrozek

@jhrozek jhrozek commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Remote MCP servers could supply an OIDC realm on a private address and reach it through an unguarded OAuth configuration fallback after the guarded preliminary discovery failed. This closes that SSRF path by carrying the existing private-IP policy into the fallback discovery request.
  • Thread blockPrivateIPs through OIDC configuration creation, apply !AllowPrivateIPs to remote OAuth discovery, and preserve private issuer support for operator-configured registry/token-source OIDC flows.
  • Add behavioral regression coverage that verifies blocked discovery never reaches a loopback listener and that explicitly permitted discovery still succeeds.

Security advisory: GHSA-cvhc-p56v-qm9r

Reported by Yanhaoxi.

Type of change

  • Bug fix
  • New feature
  • Refactoring (no behavior change)
  • Dependency update
  • Documentation
  • Other (describe):

Test plan

  • Unit tests (task test) — attempted, but the complete repository suite did not finish within the local timeout
  • E2E tests (task test-e2e)
  • Linting (task lint-fix)
  • Manual testing (describe below)

Changes

File Change
pkg/auth/oauth/oidc.go Accept and enforce the caller's private-IP discovery policy.
pkg/auth/discovery/discovery.go Apply OAuthFlowConfig.AllowPrivateIPs to fallback OIDC discovery.
pkg/auth/tokensource/tokensource.go Preserve private issuer support for operator-configured token sources.
pkg/auth/oauth/oidc_test.go Verify blocked and permitted loopback discovery using listener hit counts.
pkg/auth/discovery/discovery_test.go Verify the vulnerable fallback cannot reach a private issuer.

Does this introduce a user-facing change?

Remote authentication now refuses server-derived OIDC discovery requests to private, loopback, and link-local addresses unless the configured remote target permits private upstreams.

Implementation plan

Approved implementation plan
  1. Thread blockPrivateIPs through CreateOAuthConfigFromOIDC and its private helper, replacing the hardcoded false.
  2. Pass !config.AllowPrivateIPs from the remote discovery fallback and false from the trusted operator-configured token-source path.
  3. Update the existing private-helper test call.
  4. Add behavioral tests for blocked/permitted loopback discovery and the exact fallback branch.
  5. Leave best-effort discovery error handling, registry helpers, advisory metadata, docs, and unrelated security behavior unchanged.
  6. Run linting, tests, and a focused final code/security review.

Special notes for reviewers

The preliminary discovery errors in pkg/auth/remote/handler.go remain best-effort CIMD enrichment. Once this fallback uses the same private-IP policy, a failed guarded request cannot fall through to an unguarded retry. The complete task test invocation exceeded the local execution window; CI should provide the full unit-test result.

Remote MCP authentication can derive an OIDC issuer from an untrusted realm. The OAuth configuration fallback previously performed discovery without the private-IP dial guard, allowing requests to loopback and private hosts.

Thread the caller-selected blockPrivateIPs policy through OIDC config creation, enforce the remote flow's !AllowPrivateIPs setting, preserve private issuer access for operator-configured token sources, and add listener-based regression tests.

Security-advisory: GHSA-cvhc-p56v-qm9r

Reported-by: Yanhaoxi (https://github.com/Yanhaoxi)
@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.00%. Comparing base (3a700c5) to head (c8f5ca8).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6455      +/-   ##
==========================================
- Coverage   78.01%   78.00%   -0.01%     
==========================================
  Files         767      767              
  Lines       74147    74151       +4     
==========================================
- Hits        57843    57842       -1     
- Misses      16299    16304       +5     
  Partials        5        5              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jhrozek
jhrozek merged commit 0fb54d4 into stacklok:main Aug 29, 2026
53 of 54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants