ckan-mcp-server: DataStore Table UI resource does not validate postMessage origin (in) and posts to targetOrigin "*" (out)
Summary
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.
Affected code
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.
Impact
- Content spoofing. A frame that can
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.)
- Handshake/UX interference. Because inbound messages matching a pending
id
resolve/reject the UI's MCP requests, an attacker frame can spoof responses to
the
ui/initialize handshake or otherwise disrupt the panel.
- Outbound leakage. Posting to
'*' 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.
Proof of concept
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.
Remediation
- Validate
event.origin against the expected host origin on every inbound
message; drop messages from other origins.
- Send outbound
postMessage with an explicit target origin (the host origin
established at initialize time) instead of
'*'.
- Optionally, bind to a nonce/channel established during
ui/initialize so only
the negotiated host can drive the panel.
What the EG score is made of (scorer v4.0: the three questions the 0–10 score mixes, published apart · methodology)
The EG score (3.1): severity, escalated by confirmed exploitation. This CVE's 3.1 is its impact severity (EG Severity), not escalated.
- EG Severity
- 3.1 LOWCVSS-B, impact only: no KEV listing, EPSS or EG-KEV tier raises it.GitHub Security Advisory CVSS
- EG Likelihood
- Unknown (no EPSS on record)Unknown, not low: FIRST has published no EPSS probability for this CVE.
- Confirmed exploitation
- None on record (CISA KEV, EG-KEV Tier 1)Reported apart from the likelihood: an observed fact, not a probability.
- EG Priority
- SSVC Track at medium mission impactTrack at low or medium mission impact; Track* at high (mission-essential systems).CISA BOD 26-04: 14 days if the affected system is publicly exposed; Fix on system upgrade if it is not.Each input and its source, and whom BOD 26-04 binds: the SSVC and BOD 26-04 blocks below.
SSVC (CISA's decision table, applied by EchelonGraph)Track at low or medium mission impact; Track* at high (mission-essential systems).
A fixed version is listed under Patch Availability. Apply it within your standard update timelines.
Exploitation none (no CISA value, KEV listing or exploit code on record) · Automatable no (CISA's BOD 26-04 default) · Technical impact total (CISA's BOD 26-04 default). EchelonGraph holds no SSVC assessment of this CVE from CISA: none of these inputs is from Vulnrichment. EchelonGraph applied CISA's decision table to them; CISA publishes SSVC inputs and the table, not a decision for each CVE. Mission impact is CISA's Mission & Well-being decision point, and only you can judge it. CISA's table makes it high when Mission Prevalence is Essential — the vulnerable component "directly provides capabilities that constitute at least one MEF for at least one entity" (MEF: mission essential function) — or when Public Well-Being Impact is Irreversible: "multiple fatalities are likely", the cyber-physical system "is likely lost or destroyed", "extreme or serious externalities" are imposed on other parties, or social systems such as elections or the financial grid "are destabilized and potentially collapse". CISA's decision table
BOD 26-04 (CISA's remediation timeline, Table 1)14 days if the affected system is publicly exposed; Fix on system upgrade if it is not.
The score's inputs: In CISA KEV no (CISA's KEV catalog) · Automatable no (CISA's BOD 26-04 default) · Technical impact total (CISA's BOD 26-04 default). Where an input reads “CISA's BOD 26-04 default”, no one has published it for this CVE, and CISA's implementation guidance says: “If “Automatable” and “Technical Impact” information items about a CVE ID are not available and the CVE ID is not in the KEV Catalog, CISA will treat its values as “no” and “total,” respectively, until CISA or a third party provides metadata about the CVE ID. CISA will always provide the Vulnrichment data for a CVE ID listed in the KEV Catalog.” Whether your system is publicly exposed is yours to answer. BOD 26-04 binds US Federal Civilian Executive Branch agencies; for anyone else it is CISA's published timeline, a reference rather than an obligation. The directive · how EchelonGraph applies it