Skip to main content

MCP Registry EUVDEUVD-2026-30487

| CVE-2026-44429 MEDIUM
Cross-site Scripting (XSS) (CWE-79)
2026-05-08 https://github.com/modelcontextprotocol/registry GHSA-rqv2-m695-f8j4
5.1
CVSS 4.0 · Vendor: https://github.com/modelcontextprotocol/registry
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Obtain JWT via GitHub OAuth
  2. Delivery
    Craft server.json with quote-escaped websiteUrl
  3. Exploit
    Publish to /v0/publish endpoint
  4. Install
    Entry appears in catalogue
  5. C2
    Victim visits registry homepage
  6. Execute
    Victim searches/finds entry
  7. Impact
    Victim clicks card to expand
  8. Step 8
    Victim hovers Website link
  9. Step 9
    onmouseover fires
  10. Step 10
    Inject localStorage payload or phishing form
  11. Step 11
    Steal or redirect registry usage

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK

2 techniques across 2 tactics: Initial Access, Execution

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Exploitation requires: (1) The attacker must have a means to obtain a Registry JWT - either a valid GitHub account to exchange via /v0/auth/github-at, or the deployment must have anonymous auth enabled via /v0/auth/none. (2) The server.json websiteUrl field must contain a literal double-quote character or other quote/bracket characters not already rejected by the validator. Pre-patch versions do not reject these characters. (3) A victim must visit the public catalogue UI at GET /, search for or otherwise discover the malicious server entry, click to expand the card, and interact with (hover over) the 'Website' link in the details panel to trigger the onmouseover event. (4) The victim's browser must support HTML5 event attributes and must not override the CSP policy. Default configurations of registry.modelcontextprotocol.io and self-hosted deployments with default settings are vulnerable if running affected versions. Deployments that have already restricted /v0/publish endpoint access to trusted publishers, disabled anonymous auth, or applied stricter input validation are not vulnerable. The vulnerability is NOT dependent on non-default configuration of MCP Registry itself - the default code path is vulnerable - but exploitation scope is constrained by publish-token availability and victim interaction with the malicious link.

Impact

This vulnerability carries critical real-world risk despite the absence of a numeric CVSS score in the advisory data. The attack vector is network-based and requires only that a user browse the public registry homepage and expand a malicious listing - no authentication, no user interaction beyond hovering a link, and no browser-specific bypass required. The exploitation prerequisites are minimal: any user with a GitHub account can obtain a publish token in seconds via POST /v0/auth/github-at, and the proof-of-concept demonstrates the exact payload. The impact is high-consequence: the injected script runs on the official registry origin (registry.modelcontextprotocol.io), granting it same-origin access to localStorage (where the user's base URL and custom registry URL are stored), the ability to issue XHR requests with connect-src *, and capability to inject fake authentication flows to phish Registry JWTs. The stored nature of the XSS means the malicious entry persists and affects every subsequent visitor until removed. The presence of a concrete, verified patch in version 1.7.7 and the availability of remediation strategies (tighter input validation, attribute-safe encoding, or DOM methods instead of string concatenation) indicate vendor acknowledgment and swift response. Organizations running versions prior to 1.7.7 should prioritize upgrading immediately. The CSP weakness ('unsafe-inline') is not independent of the root cause - without the attribute-breakout, inline event handlers on the page itself would still be constrained; the interaction of weak CSP and unsafe escaping is the critical failure chain.

Exploit ScenarioDerived

An attacker with a GitHub account (or access to anonymous auth) obtains a Registry JWT by exchanging their GitHub token via POST /v0/auth/github-at. They publish a server with websiteUrl set to https://example.com/"onmouseover=alert(document.domain)//, breaking the href attribute and appending an event handler. Any user visiting the official registry homepage, searching for the malicious server, clicking the card to expand details, and hovering over the 'Website' link will trigger the injected onmouseover handler, executing arbitrary JavaScript in the registry origin. The attacker can then steal or manipulate localStorage entries (base URL, custom registry URL) to redirect the user to a malicious registry, or inject a fake login form to phish the user's Registry JWT, granting the attacker access to that user's publish namespace.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – May 08, 2026

Stored cross-site scripting in MCP Registry's catalogue UI allows any user with a publish token to inject arbitrary event handlers via the websiteUrl field by breaking out of an href attribute with an unescaped double-quote character. The server-side URL validator accepts quotes and the client-side escapeHtml helper fails to encode them in attribute context, enabling attackers to execute JavaScript on the registry.modelcontextprotocol.io origin with access to localStorage, XHR, and auth tokens. Vendor-released patch version 1.7.7 available; actively confirmed via proof-of-concept.

RemediationAI

Upgrade to MCP Registry version 1.7.7 or later, which implements server-side validation rejecting URLs containing quote characters (", '), angle brackets (<, >), whitespace (space, tab, newline, carriage return), and other problematic characters in the websiteUrl field. The patch adds an explicit character-set check in internal/validators/validators.go that rejects invalid characters and instructs publishers to percent-encode such characters if needed (e.g., %20 for space). The fix is applied via commit 78b7bbde07948049b916d76b4769faee461ff930 and PR #1249. For deployments unable to upgrade immediately, apply compensating controls: (1) Disable the /v0/publish endpoint or restrict it to trusted publishers only via authentication or IP allowlisting, preventing untrusted users from planting poisoned entries. (2) Remove 'unsafe-inline' from the script-src CSP directive after auditing all inline scripts on the page, preventing inline event handlers from executing even if attribute-breakout is achieved. (3) Implement Content-Security-Policy stricter than the current policy, using a nonce-based or hash-based approach for legitimate inline scripts. (4) Use DOM attribute-setting methods (element.setAttribute('href', value)) instead of string interpolation for URL attributes in client-side code, as setAttribute bypasses HTML tokenization. Monitor published entries for suspicious websiteUrl values containing special characters, and remove or revoke access for malicious publishers.

Affected VersionsENISA

registry < 1.7.7

Affected Packages

go github.com/modelcontextprotocol/registry fix: 1.7.7
euvd registry fix: 1.7.7

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in go, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The vulnerability stems from a mismatch between HTML parsing and serialization contexts. The Go net/url.Parse function in internal/validators/validators.go accepts literal double-quotes in URL path components without rejection, and the existing validateWebsiteURL function only checks scheme, absoluteness, and parseability - not RFC 3986 character restrictions. The client-side sink is the homegrown escapeHtml function in internal/api/handlers/v0/ui_index.html (lines 494-498), which performs a textContent → innerHTML round-trip. Per HTML5 serialization spec §13.3, this round-trip encodes only &, <, >, and U+00A0 within text nodes; " and ' are not encoded because they are not special in text-content context. When the escaped value is then interpolated into a double-quoted href attribute via string concatenation on line 432, the literal " breaks the attribute boundary, allowing subsequent characters (e.g., onmouseover=alert(1)//) to be parsed as attribute syntax. The CSP policy script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com explicitly permits 'unsafe-inline', which includes inline event handlers, so the injected payload executes. The attack surface is publisher-controlled via the server.json websiteUrl field, accessible to any user who obtains a Registry JWT through /v0/auth/github-at (GitHub OAuth) or /v0/auth/none (if anonymous auth is enabled). The poisoned entry is then displayed to all visitors of the catalogue UI at GET /.

Know when Canonical gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/modelcontextprotocol/registry) PRIMARY 5.1 MEDIUM
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:N/VA:N/SC:N/SI:L/SA:L
SUSE MEDIUM

Primary rating from Vendor (https://github.com/modelcontextprotocol/registry).

CVSS VectorVendor: https://github.com/modelcontextprotocol/registry

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
None
Privileges Required
Low
User Interaction
Passive
Vulnerable system: Confidentiality
None
Vulnerable system: Integrity
None
Vulnerable system: Availability
None
Subsequent system: Confidentiality
None
Subsequent system: Integrity
Low
Subsequent system: Availability
Low

Lifecycle Timeline

2
CVSS changed
May 14, 2026 - 21:22 NVD
5.1 (MEDIUM)
CVE Published
May 08, 2026 - 17:18 nvd
MEDIUM

DescriptionCVE.org

Summary

The public catalogue UI served at GET / (file internal/api/handlers/v0/ui_index.html) is vulnerable to stored cross-site scripting via the server.websiteUrl field of any published server.json. Server-side validation in internal/validators/validators.go (validateWebsiteURL) only checks that the URL parses, is absolute, and uses the https scheme; it does not reject quote characters. Client-side, the value is interpolated into a double-quoted href attribute via innerHTML, using a homegrown escapeHtml helper that performs the standard textContent → innerHTML round-trip. Per the HTML serialisation algorithm, that round-trip encodes only &, <, > and U+00A0 inside text nodes - it does not encode " or '. A literal " in websiteUrl therefore breaks out of the href attribute, allowing arbitrary on* event handlers to be appended to the same <a> element. The Content-Security-Policy on / is script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com, so the injected event handlers execute.

Any user able to obtain a publish token (e.g. via POST /v0/auth/github-at with their own GitHub account, or POST /v0/auth/none on a deployment that has anonymous auth enabled) can plant a poisoned record visible to every visitor of the registry homepage.

Affected component

  • Validator: internal/validators/validators.go - validateWebsiteURL (lines 153-199)
  • Sink: internal/api/handlers/v0/ui_index.html - toggleDetails(card, item) at line 432, the href attribute built around escapeHtml(server.websiteUrl)
  • Helper: escapeHtml defined at internal/api/handlers/v0/ui_index.html lines 494-498

Proof of concept

  1. Obtain a Registry JWT for any namespace you control (a GitHub OAuth exchange against a throwaway account suffices):
bash
   TOKEN=$(curl -sS -X POST https://registry.modelcontextprotocol.io/v0/auth/github-at \
        -H 'Content-Type: application/json' \
        -d '{"github_token":"<gh-pat>"}' | jq -r .registry_token)
  1. Publish a server with a poisoned websiteUrl. The literal " is preserved end-to-end:
bash
   curl -sS -X POST https://registry.modelcontextprotocol.io/v0/publish \
     -H "Authorization: Bearer $TOKEN" \
     -H 'Content-Type: application/json' \
     --data-binary @- <<'EOF'
   {
     "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
     "name":  "io.github.<your-account>/xss-poc",
     "version": "0.0.1",
     "description": "hover the website link",
     "websiteUrl": "https://example.com/\"onmouseover=alert(document.domain)//"
   }
   EOF
  1. Visit https://registry.modelcontextprotocol.io/, search for xss-poc, click the card to expand it, then hover the Website link in the details panel. The injected onmouseover fires and alert(document.domain) runs on the registry.modelcontextprotocol.io origin.

Why server-side validation does not catch this

Go's net/url.Parse accepts literal " in the path component:

input="https://example.com/\"onmouseover=alert(1)//"  IsAbs=true  Scheme="https"  Path="/\"onmouseover=alert(1)//"

Neither the Huma format:"uri" annotation nor validateWebsiteURL's scheme/IsAbs triplet rejects this string. The architecture's existing protection - repository.url is regex-locked to ^https?://(www\.)?github\.com/[\w.-]+/[\w.-]+/?$ and therefore cannot contain quotes - does not extend to websiteUrl, which has no allowlist.

Why client-side escapeHtml does not catch this

js
function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

Per the HTML5 spec (§13.3 Serialising HTML fragments), the only characters encoded inside the text content of an element are &, <, >, and U+00A0. " and ' are not encoded because in a text-content context they are not special. The helper is therefore safe in element-text contexts (where it is correctly used for name, version, description, etc.) but unsafe inside an attribute value, which is precisely where it is invoked for href on lines 432 and 426.

Impact

  • Stored XSS on the official MCP Registry homepage. The malicious entry sits in the public catalogue alongside legitimate ones; any user expanding the entry triggers the payload.
  • Because the page is served on the official registry.modelcontextprotocol.io origin, the injected script can:
  • Read and overwrite localStorage (baseUrl, customUrl), pinning the user's subsequent reads to an attacker-controlled "Custom" base URL.
  • Issue any same-origin or cross-origin XHR (connect-src * is granted).
  • Phish for Registry JWTs by injecting fake auth flows on the trusted origin.
  • The CSP script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com does not block this because 'unsafe-inline' permits inline event-handler attributes.

Suggested remediation (any one suffices)

  1. Replace the homegrown escapeHtml with an attribute-safe encoder that also escapes ", ', backtick, and = - the OWASP HTML attribute-encoding rule.
  2. Avoid building the href via string templates. Use setAttribute('href', value) instead - setAttribute is not subject to HTML tokenisation, so no breakout is possible.
  3. Tighten validateWebsiteURL to reject any URL whose raw bytes contain ", ', <, >, , \t, or \n, or - conservatively - store the canonical re-serialised form (parsedURL.String() percent-encodes such characters in the path).
  4. Drop 'unsafe-inline' from script-src after auditing the inline scripts on the page.

Approach (3) is the smallest server-side change and immediately neutralises the exploit for any new publishes; approaches (1) or (2) close the class of bug at the sink so future fields with similar patterns are safe by default.

Threat Intelligence Overview

EPSS Score
0.0%
Top 86% exploitable
Threat Intel
1
1 source
Data Quality
8 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact· derived
Medium
Technical Impact
Partial

Priority Score

26
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +26
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.

CVE-2011-3544 CRITICAL POC
9.8 Oct 19

Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug

CVE-2019-11043 CRITICAL POC
9.8 Oct 28

In PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 in certain configurations of FPM setup it

CVE-2014-6271 CRITICAL POC
9.8 Sep 24

GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which

CVE-2013-0422 CRITICAL POC
9.8 Jan 10

Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using

CVE-2016-3714 HIGH POC
8.4 May 05

The (1) EPHEMERAL, (2) HTTPS, (3) MVG, (4) MSL, (5) TEXT, (6) SHOW, (7) WIN, and (8) PLT coders in ImageMagick before 6.

CVE-2017-12617 HIGH POC
8.1 Oct 04

When running Apache Tomcat versions 9.0.0.M1 to 9.0.0, 8.5.0 to 8.5.22, 8.0.0.RC1 to 8.0.46 and 7.0.0 to 7.0.81 with HTT

CVE-2016-8735 CRITICAL POC
9.8 Apr 06

Remote code execution is possible with Apache Tomcat before 6.0.48, 7.x before 7.0.73, 8.x before 8.0.39, 8.5.x before 8

CVE-2014-7169 CRITICAL POC
9.8 Sep 25

GNU Bash through 4.3 bash43-025 processes trailing strings after certain malformed function definitions in the values of

CVE-2014-0160 HIGH POC
7.5 Apr 07

The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packe

CVE-2016-5195 HIGH POC
7.0 Nov 10

Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3 allows local users to gain privileges by lev

CVE-2013-2423 LOW POC
3.7 Apr 17

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 17 and earlier, and

CVE-2023-4911 HIGH POC
7.8 Oct 03

Local privilege escalation in the GNU C Library (glibc) dynamic loader ld.so allows unprivileged local users on affected

Vendor StatusVendor

SUSE

Severity: Moderate
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP5 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP6 Affected
openSUSE Leap 15.5 Affected

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