Skip to content

fix: use SSRF-safe HTTP client for MCP OAuth authorization server metadata fetch#3035

Merged
ronan-thibaut-glitch merged 2 commits into
mainfrom
fix/ssrf-mcp-oauth
Jun 9, 2026
Merged

fix: use SSRF-safe HTTP client for MCP OAuth authorization server metadata fetch#3035
ronan-thibaut-glitch merged 2 commits into
mainfrom
fix/ssrf-mcp-oauth

Conversation

@ronan-thibaut-glitch

@ronan-thibaut-glitch ronan-thibaut-glitch commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

Replaces the unguarded &http.Client{Timeout: 5s} used as
oauth.metadataClient in PerformOAuthLogin with
httpclient.NewSafeClient(5s, false), preserving the original timeout
while adding the SSRF-safe transport and redirect cap.

Why

PerformOAuthLogin fetches /.well-known/oauth-protected-resource from
the configured MCP server, then follows the authorization_servers URL
returned in that response. That second URL is attacker-controlled -- a
malicious MCP server can point it at an internal host (e.g.
http://169.254.169.254/). The unguarded metadataClient would fetch
it unconditionally.

Closes #3034.

References

@ronan-thibaut-glitch ronan-thibaut-glitch requested a review from a team as a code owner June 9, 2026 14:27
@aheritier aheritier added area/mcp MCP protocol, MCP tool servers, integration area/security Authentication, authorization, secrets, vulnerabilities kind/security Security fix or hardening PR labels Jun 9, 2026

@docker-agent docker-agent left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Assessment: 🔴 CRITICAL

The PR introduces an SSRF-safe HTTP client for MCP OAuth metadata fetches, but the fix is incomplete. The newly created safe client (o.metadataClient) is only wired into the second fetch (getAuthorizationServerMetadata), while the first outbound request — GET /.well-known/oauth-protected-resource — still uses the unguarded http.DefaultClient. A serverURL pointing at an internal host will bypass SSRF protection on that initial call.

tokenStore := NewKeyringTokenStore()

o := &oauth{metadataClient: &http.Client{Timeout: 5 * time.Second}}
o := &oauth{metadataClient: httpclient.NewSafeClient(5*time.Second, false)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[HIGH] Incomplete SSRF fix — first metadata fetch still uses http.DefaultClient

The safe client created here (o.metadataClient) is only used by the subsequent o.getAuthorizationServerMetadata call. The first outbound request in this function — the GET /.well-known/oauth-protected-resource fetch 16 lines below — still uses the bare http.DefaultClient:

resp, err := http.DefaultClient.Do(resourceReq)  // line 40 — unguarded

This means the PR's SSRF protection is incomplete. Any serverURL whose hostname resolves to a private/internal address (e.g. http://192.168.1.1/, http://169.254.169.254/) will still trigger an unguarded outbound request during the first fetch. The fix should use o.metadataClient.Do(resourceReq) instead of http.DefaultClient.Do(resourceReq).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed -- both fetches now use o.metadataClient. The agent config can be loaded from a remote URL or OCI reference, making serverURL attacker-influenced in those cases.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed fixed — both metadata fetches now use the safe client. Thanks for the additional context about remote config loading; that makes the attack surface much clearer and confirms why guarding both requests was essential.

@ronan-thibaut-glitch ronan-thibaut-glitch self-assigned this Jun 9, 2026
@ronan-thibaut-glitch ronan-thibaut-glitch merged commit 77176a8 into main Jun 9, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/mcp MCP protocol, MCP tool servers, integration area/security Authentication, authorization, secrets, vulnerabilities kind/security Security fix or hardening PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: SSRF protection missing on MCP OAuth metadata fetch and remote transport data plane

4 participants