Skip to content

fix(oauth): use discoverOAuthFromWWWAuthenticate for 401-triggered OAuth discovery#19626

Closed
yuvrajangadsingh wants to merge 5 commits intogoogle-gemini:mainfrom
yuvrajangadsingh:fix/oauth-resource-metadata-discovery
Closed

fix(oauth): use discoverOAuthFromWWWAuthenticate for 401-triggered OAuth discovery#19626
yuvrajangadsingh wants to merge 5 commits intogoogle-gemini:mainfrom
yuvrajangadsingh:fix/oauth-resource-metadata-discovery

Conversation

@yuvrajangadsingh
Copy link
Copy Markdown
Contributor

Fixes #18760

Problem

handleAutomaticOAuth() passes the resource_metadata URI from the WWW-Authenticate header to discoverOAuthConfig(), which expects a base server URL. Since resource_metadata is already a .well-known URL, discoverOAuthConfig constructs a double-nested path like:

https://example.com/.well-known/oauth-protected-resource/.well-known/oauth-protected-resource

This 404s. The root-based fallback then fetches the root metadata but validation fails with ResourceMismatchError because it compares the root resource against the .well-known URI instead of the actual server URL.

Fix

Replace discoverOAuthConfig(resourceMetadataUri) with discoverOAuthFromWWWAuthenticate(wwwAuthenticate, serverUrl), which already exists in oauth-utils.ts and correctly:

  1. Fetches the resource metadata directly from the resource_metadata URI
  2. Validates the resource field against the actual MCP server URL (per RFC 9728 §7.3)
  3. Discovers the authorization server from the metadata

The base-URL fallback path (discoverOAuthConfig) is preserved for 401 responses that don't include a resource_metadata in the WWW-Authenticate header.

Testing

Updated existing tests in mcp-client.test.ts to mock discoverOAuthFromWWWAuthenticate on the primary path and discoverOAuthConfig on the fallback path. All 60 tests pass.

@yuvrajangadsingh yuvrajangadsingh requested a review from a team as a code owner February 20, 2026 09:00
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @yuvrajangadsingh, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the OAuth discovery process that occurred when a 401 Unauthorized response was received. Previously, the system would incorrectly attempt to discover OAuth configuration from an already well-known resource metadata URI, resulting in malformed URLs and authentication failures. The fix re-architects the discovery mechanism to correctly interpret the WWW-Authenticate header, ensuring proper resource validation and maintaining a robust fallback for less common authentication challenges.

Highlights

  • OAuth Discovery Fix: Resolved an issue where discoverOAuthConfig was incorrectly used with a .well-known URI from the WWW-Authenticate header, leading to double-nested paths and authentication failures.
  • Corrected OAuth Flow: Implemented discoverOAuthFromWWWAuthenticate to properly parse the WWW-Authenticate header, fetch resource metadata, and validate the resource against the actual server URL as per RFC 9728.
  • Fallback Mechanism: Maintained the discoverOAuthConfig as a fallback for scenarios where the WWW-Authenticate header does not include a resource_metadata URI.
  • Test Updates: Updated existing tests in mcp-client.test.ts to reflect the new OAuth discovery logic, including mocking discoverOAuthFromWWWAuthenticate and handling its null return for fallback scenarios.
Changelog
  • packages/core/src/tools/mcp-client.test.ts
    • Switched OAuth discovery mock from discoverOAuthConfig to discoverOAuthFromWWWAuthenticate.
    • Removed capturedTransport variable and its related assertion.
    • Added an assertion to verify discoverOAuthFromWWWAuthenticate is called with the correct arguments.
    • Introduced a mock for discoverOAuthFromWWWAuthenticate to return null for testing the fallback path.
  • packages/core/src/tools/mcp-client.ts
    • Adjusted import statements for SDK types to improve readability.
    • Modified handleAutomaticOAuth to prioritize discoverOAuthFromWWWAuthenticate for initial OAuth discovery.
    • Updated the fallback logic to correctly use extractBaseUrl before calling discoverOAuthConfig.
    • Removed a redundant serverUrl declaration within the handleAutomaticOAuth function.
Activity
  • No specific activity (comments, reviews, or progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly fixes a bug in the automatic OAuth discovery process by leveraging the discoverOAuthFromWWWAuthenticate utility to properly fetch and validate metadata as per RFC 9728. However, it introduces a Server-Side Request Forgery (SSRF) vulnerability in the automatic OAuth discovery flow. The client fetches the resource_metadata URI provided in the WWW-Authenticate header without verifying its origin, which could allow a malicious server to trigger requests to internal network resources. An origin check is recommended before fetching the metadata URI. The accompanying test updates are solid, improving robustness by correctly mocking the new code paths, and the changes generally enhance code clarity.

@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request correctly implements the use of discoverOAuthFromWWWAuthenticate to handle OAuth discovery triggered by 401 responses, resolving issues with double-nested paths and improving compliance with RFC 9728. However, it introduces a potential SSRF vulnerability by fetching the resource_metadata URI directly from the untrusted WWW-Authenticate header without origin validation, violating the 'fail-closed' security principle. Additionally, a critical regression was introduced in the import section of mcp-client.ts, where value-level Zod schemas were merged into a type-only import block, which will cause runtime errors when those schemas are accessed as values.

@gemini-cli gemini-cli bot added priority/p2 Important but can be addressed in a future release. area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! labels Feb 20, 2026
…uth discovery

The reactive OAuth flow passed the resource_metadata URI (a .well-known URL)
to discoverOAuthConfig(), which expects a base server URL and constructs
.well-known paths from it. This caused double-nested paths that 404, followed
by a ResourceMismatchError when the root fallback compared against the wrong
expected resource.

Use the existing discoverOAuthFromWWWAuthenticate() method which correctly
fetches the resource metadata directly and validates against the actual
server URL per RFC 9728.

Fixes google-gemini#18760
@yuvrajangadsingh yuvrajangadsingh force-pushed the fix/oauth-resource-metadata-discovery branch from 2b4a670 to 198b285 Compare February 20, 2026 09:25
@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly fixes a bug in the OAuth discovery flow for 401 responses. However, it introduces or exposes a Server-Side Request Forgery (SSRF) vulnerability by fetching URIs provided in the WWW-Authenticate header without proper validation. This could allow a malicious MCP server to probe the user's local network or interact with internal services. The issue is exacerbated by network requests occurring before user consent, which is against best practices for OAuth flows.

Validate that the resource_metadata URI from the WWW-Authenticate header
has the same origin as the MCP server URL before fetching it. This prevents
a malicious MCP server from directing the client to fetch internal network
resources or cloud metadata endpoints.
@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request resolves the issue of handleAutomaticOAuth generating invalid double-nested .well-known URIs by implementing discoverOAuthFromWWWAuthenticate to correctly fetch and validate OAuth metadata from the WWW-Authenticate header, adhering to RFC 9728. Although an origin check was introduced to prevent potential SSRF vulnerabilities, the current implementation remains susceptible to a bypass via HTTP redirects, as fetch calls follow redirects by default, which could allow probing of internal network resources. The changes are well-tested and maintain backward compatibility, generally enhancing the robustness of the OAuth discovery process.

@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist
Copy link
Copy Markdown
Contributor

That's an excellent catch and a crucial security enhancement, @yuvrajangadsingh! Adding redirect: 'error' to the fetchProtectedResourceMetadata call effectively mitigates the potential SSRF vulnerability by preventing redirects to internal resources. This directly addresses the concern I raised in the previous review regarding the redirect vector. Thank you for implementing this important fix!

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively resolves a bug in the OAuth discovery logic by correctly using discoverOAuthFromWWWAuthenticate and introduces important security enhancements to prevent Server-Side Request Forgery (SSRF) vulnerabilities, specifically by disabling redirects for resource_metadata fetches and enforcing a same-origin policy. However, the SSRF protection is incomplete as it does not cover the subsequent fetch of authorization server metadata or validate the authorization server URLs themselves. These gaps could still allow a malicious MCP server to probe internal network resources. It is recommended to apply the same redirect policy to all metadata fetches and implement IP/origin validation for authorization server URLs.

@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request aims to address issues with double-nested .well-known URIs during OAuth discovery by switching to discoverOAuthFromWWWAuthenticate and introduces security controls like disabling redirects and validating against private hostnames. However, the implemented SSRF protection via isPrivateHost is incomplete, inconsistently applied, and easily bypassable, violating the 'fail-closed' principle for security checks and posing a significant security risk. The isPrivateHost implementation itself is fragile and susceptible to bypasses using various IP address representations, and is omitted in certain critical code paths like the discoverOAuthConfig fallback.

…s, broader IP coverage, protect discoverOAuthConfig path
@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request successfully addresses the OAuth discovery issue where double-nested .well-known paths were being constructed, leading to 404 errors. By switching to discoverOAuthFromWWWAuthenticate, the code now correctly handles the resource_metadata URI provided in the WWW-Authenticate header and validates it against the actual MCP server URL as per RFC 9728. Additionally, the PR introduces important security enhancements to mitigate SSRF risks, including disabling redirect following in metadata fetches and implementing a robust check to block private or internal hostnames. The changes are well-tested and maintain high code quality.

@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

@nicolo-ribaudo @nichochar would love a maintainer review when you get a chance — fixes the OAuth discovery bug in #18760 where 401-triggered flows fail for path-based MCP servers, plus comprehensive SSRF hardening (origin checks, redirect protection, private host blocking). all tests passing and gemini-code-assist is clean.

@yuvrajangadsingh
Copy link
Copy Markdown
Contributor Author

Closing — #19038 was merged to fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! priority/p2 Important but can be addressed in a future release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(oauth): 401-triggered OAuth discovery fails for path-based MCP servers due to misrouted resource_metadata URI

1 participant