Skip to main content

MCP Registry CVE-2026-44428

LOW
Server-Side Request Forgery (SSRF) (CWE-918)
2026-05-08 https://github.com/modelcontextprotocol/registry GHSA-95c3-6vvw-4mrq
2.1
CVSS 4.0 · GitHub Advisory

Severity by source

GitHub Advisory PRIMARY
2.1 LOW
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
A
Scope
X

Lifecycle Timeline

4
CVSS changed
May 14, 2026 - 22:22 NVD
2.1 (LOW)
Source Code Evidence Fetched
May 08, 2026 - 17:45 vuln.today
Analysis Generated
May 08, 2026 - 17:45 vuln.today
CVE Published
May 08, 2026 - 17:06 nvd
LOW

DescriptionGitHub Advisory

[SECURITY] registry_001 Vulnerability Report

While analyzing the code logic, an area that may lead to unintended behavior under specific conditions was discovered.

Overview

  • Verified Version: c5c4b9e8890dd5754bee889b2f1417f4fe3b5ce5
  • Vulnerability Type: Authentication bypass via cross-registry OIDC token replay
  • Affected Location: cmd/publisher/commands/login.go:67-105,130-135,199-224; cmd/publisher/auth/github-oidc.go:24-38,58-75,108-165; internal/api/handlers/v0/auth/github_oidc.go:75-135,229-277,280-296
  • Trigger Scenario: a workflow invokes mcp-publisher login github-oidc --registry <other-registry> (or equivalent publish flow) and the publisher still requests a GitHub Actions ID token with the shared audience mcp-registry; any other registry deployment running this code can replay that token to its own /v0/auth/github-oidc endpoint and mint a publish-capable registry JWT for the same GitHub owner namespace.

Root Cause

The client-side and server-side GitHub OIDC flow is bound only to a global audience string, not to the specific registry instance being targeted. On the client side, the publisher always appends audience=mcp-registry when requesting the GitHub Actions ID token, regardless of the selected --registry URL. On the server side, the exchange endpoint validates only that same fixed audience and then derives publish permissions directly from repository_owner. As a result, a token legitimately obtained while interacting with one registry deployment remains acceptable to any other deployment that shares the same code and audience string.

Source-to-Sink Chain

  1. Source

cmd/publisher/commands/login.go:67-105,130-135,199-224 parses the user-controlled --registry flag into flags.RegistryURL, creates a GitHubOIDCProvider, and calls authProvider.GetToken(ctx) for the chosen authentication method.

  1. Propagation

cmd/publisher/auth/github-oidc.go:24-38 obtains an OIDC token and immediately exchanges it against the selected registry URL. cmd/publisher/auth/github-oidc.go:58-75 builds exchangeURL := o.registryURL + "/v0/auth/github-oidc" and posts the GitHub token to whichever registry instance was selected. cmd/publisher/auth/github-oidc.go:108-165 constructs fullURL := requestURL + "&audience=mcp-registry" and therefore requests the same audience for every registry deployment.

  1. Sink

internal/api/handlers/v0/auth/github_oidc.go:75-135 validates only the shared audience value passed into ValidateToken. internal/api/handlers/v0/auth/github_oidc.go:254-277 calls h.validator.ValidateToken(ctx, oidcToken, "mcp-registry") and, on success, signs a new registry JWT. internal/api/handlers/v0/auth/github_oidc.go:280-296 converts claims.RepositoryOwner into the publish permission pattern io.github.<owner>/*, which is then embedded into the new registry JWT.

Exploitation Preconditions

  1. The victim uses the GitHub Actions OIDC publishing path.
  2. The victim workflow targets another registry deployment first, such as staging, self-hosted infrastructure, or an attacker-controlled registry URL.
  3. The receiving registry deployment can observe the posted OIDC token and replay it before expiry to another registry deployment running the same shared audience configuration.

Risk

This breaks deployment isolation between registry instances. A token issued for one registry interaction can be replayed across trust boundaries, allowing one deployment to impersonate the same GitHub owner identity on another deployment.

Impact

An attacker-controlled or compromised registry deployment can mint a valid registry JWT on another deployment and inherit publish permissions for the victim GitHub owner namespace. In practical terms, this enables unauthorized publication or update actions for names such as io.github.<owner>/* on the victim registry instance.

Remediation

  1. Replace the shared audience string with a registry-specific audience, such as a deployment-specific client ID or origin-derived identifier.
  2. Ensure the publisher requests the audience that matches the exact registry instance it is targeting, and ensure the server validates that same instance-specific value.
  3. Consider binding the exchange to additional deployment-specific claims so that a token captured by one registry cannot be replayed on another.
  4. Add regression tests that cover cross-deployment replay attempts between different registry URLs.

AnalysisAI

MCP Registry's GitHub OIDC token exchange allows cross-registry replay attacks due to use of a shared global audience string instead of registry-specific identifiers. An attacker controlling or observing any registry deployment can capture a legitimately issued OIDC token and replay it to another registry instance sharing the same codebase to obtain publish-capable JWTs for the victim GitHub owner namespace, breaking deployment isolation. The vulnerability affects all versions prior to 1.7.6; vendor-released patch available.

Technical ContextAI

MCP Registry integrates GitHub Actions OIDC (OpenID Connect) for publisher authentication. The vulnerable flow: client requests a GitHub Actions ID token with audience 'mcp-registry' regardless of target registry URL; server validates only that fixed audience string and derives publish permissions from the repository_owner claim. The root cause is CWE-918 (Server-Side Request Forgery) manifested as trust boundary bypass - the OIDC token audience parameter is not bound to the specific registry instance (hostname, scheme, or deployment identifier), allowing any registry deployment validating the same audience to accept tokens issued for other deployments. The GitHub OIDC flow involves: cmd/publisher/commands/login.go parses --registry URL; cmd/publisher/auth/github-oidc.go requests GitHub ID token with shared audience and exchanges it at the chosen registry endpoint; internal/api/handlers/v0/auth/github_oidc.go validates the audience without registry-specificity and mints a new JWT with publish permissions pattern io.github.<owner>/*.

RemediationAI

Vendor-released patch: upgrade to MCP Registry version 1.7.6 or later. The fix replaces the shared hardcoded audience string 'mcp-registry' with registry-specific audiences derived from the registry URL scheme and hostname (e.g., 'https://registry.modelcontextprotocol.io'). On the client side, cmd/publisher/auth/github-oidc.go now calls audienceFromRegistryURL() to compute instance-specific audience before requesting the GitHub OIDC token, and passes this audience to getOIDCTokenFromGitHub(). On the server side, internal/api/handlers/v0/auth/github_oidc.go now reads the audience from environment variable MCP_REGISTRY_GITHUB_OIDC_AUDIENCE and validates tokens against that configured value instead of the hardcoded string. Deployment requirement: set MCP_REGISTRY_GITHUB_OIDC_AUDIENCE environment variable to the appropriate registry URL (scheme + hostname) for each deployment; production should use 'https://registry.modelcontextprotocol.io', staging 'https://staging.registry.modelcontextprotocol.io', etc. No workarounds are available for versions prior to 1.7.6 that do not break functionality - avoid using the GitHub OIDC publishing path across multiple registry instances if versions cannot be immediately upgraded. Patch references: https://github.com/modelcontextprotocol/registry/pull/1229, https://github.com/modelcontextprotocol/registry/commit/3f89fc2b1fb34fd49f3c0e1b39e964a5c67b613f.

Share

CVE-2026-44428 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy