
Loading

Loading
We use strictly necessary cookies to run this site, and analytics cookies to understand how it's used. See our Privacy Policy for details.
A GitHub-reviewed security advisory, not necessarily under active exploitation the way our CISA KEV advisories are, but a real, disclosed vulnerability in an open-source dependency.
Affected packages
Vulnerable: < 0.4.112
Patched in 0.4.112
Details
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.Talk to us about this
Find out whether this dependency (or others like it) is actually reachable in your codebase.
Get help patching, or building dependency-scanning into your pipeline going forward.
A secure code review or supply chain review finds this before an advisory does.