Live › vulnerability › CVE-2026-76894
Go to dashboardThe ckan-mcp-server MCP Apps DataStore table UI accepts postMessage from any origin and sends its messages with target origin '*'. A frame that can message the UI can render fabricated rows and phishing links, and spoof MCP handshake responses, but the sources say it cannot run script (values are HTML-escaped).
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-23 19:11 UTC. All times on this page are UTC.
| Product | Ecosystem | Affected | Fixed in |
|---|
| @aborruso/ckan-mcp-server | npm | < 0.4.112 | 0.4.112 |
Unknown from the sources.
Upgrade @aborruso/ckan-mcp-server to 0.4.112 or later.
Each row is the first time that source carried this signal. The analyst’s rows are its own findings.
The MCP Apps UI resource (an interactive DataStore table rendered in the host's webview/iframe) communicates with its parent via postMessage. Its inbound message listener performs no event.origin validation, and its outbound messages are sent with target origin '*'. Any window/frame able to reach the document can inject data into the table and interfere with the MCP UI handshake, and the UI's own JSON-RPC messages are broadcast without an origin restriction.
src/resources/datastore-table-ui.ts (inline HTML):
window.addEventListener('message', function (event) {
var msg = event.data; // no check of event.origin
if (!msg || typeof msg !== 'object') return;
if (msg.id !== undefined && _pending[msg.id]) { ... resolve/reject pending MCP request ... }
...
if (data && (data.fields || data.records)) initTable(data); // renders attacker-supplied data
});
// outbound:
window.parent.postMessage({ jsonrpc: '2.0', id: id, method: method, params: params || {} }, '*');
mcpNot: window.parent.postMessage({ jsonrpc:'2.0', method:method, params:params||{} }, '*');
There is no allowlist of accepted origins for inbound messages and no fixed target origin for outbound messages.
postMessage to the UI can supply
arbitrary fields/records, causing the table to render fabricated rows and
links (e.g. a phishing __link_url) that appear to come from the queried
portal. (Values are HTML-escaped, so this is display spoofing, not script
injection — no XSS.)id
resolve/reject the UI's MCP requests, an attacker frame can spoof responses to
the ui/initialize handshake or otherwise disrupt the panel.'*' means the UI's JSON-RPC messages are
delivered to whatever the parent origin is; if the resource is ever embedded by
a context other than the trusted host, those messages leak to it.Exploitability depends on the host embedding model (in a correct MCP Apps host the parent is the trusted host, which limits who can message the frame), so this is a hardening / defense-in-depth issue rather than a directly remotely-triggerable one — hence Low.
poc/verify-no-origin-check.mjs — static confirmation that the listener has no
origin check and outbound uses '*':
[x] validates event.origin : NO
[x] outgoing postMessage targetOrigin : '*' (any)
RESULT: VULNERABLE
poc/parent-spoof-poc.html — a page that embeds the UI and injects fabricated
rows cross-origin with no handshake; the UI renders them.
event.origin against the expected host origin on every inbound
message; drop messages from other origins.postMessage with an explicit target origin (the host origin
established at initialize time) instead of '*'.ui/initialize so only
the negotiated host can drive the panel.This page as .md · .json · in your agent: get_signal("CVE-2026-76894")
GitHub Advisory Database, CC-BY 4.0. Posts quoted belong to their authors.