ckan-mcp-server CVE-2026-76894
LOWAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessReach UI iframe from untrusted frame
-
ExploitpostMessage sent with no origin check
-
ExecutionInject fabricated records or spoof ui/initialize
-
ImpactUser views spoofed/phishing table content
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V15 - Secure Coding and Architecture Data authenticity verification
|
| Exploitation Conditions | Requires the datastore-table-ui resource to be embedded in a context where a window/frame OTHER than the trusted MCP Apps host can postMessage to the iframe - i.e. an incorrect or non-standard embedding model, or a malicious parent/sibling frame reaching the document. The inbound listener has no event.origin allowlist and outbound messages use targetOrigin '*'. Key LIMITING factors: in a correct MCP Apps host the parent is the trusted host (sharply restricting who can message the frame); the user must actually open and view the DataStore table panel (UI:R); impact is confined to content/UX spoofing and leakage of the UI's own JSON-RPC messages - values are HTML-escaped so there is no code execution. |
| Impact | All signals converge on LOW real-world priority. The provided CVSS 3.1 vector (AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N = 3.1) reflects a network-reachable but high-complexity issue requiring user interaction and yielding only limited confidentiality impact. No EPSS score is provided and the CVE is not in CISA KEV, so there is no evidence of active or probable exploitation. POC code does exist (poc/verify-no-origin-check.mjs static check and poc/parent-spoof-poc.html demonstrating cross-origin row injection), but POC availability is distinct from exploitation - no public exploit campaign is identified. No SSVC decision data is supplied. Critically, the vendor advisory itself frames this as a hardening / defense-in-depth gap rather than a directly remotely-triggerable flaw: in a correct MCP Apps host the parent IS the trusted host, which structurally limits who can postMessage to the frame, hence the AC:H and the Low rating. One signal conflict to note: the input Tags label this 'XSS', but the advisory explicitly states values are HTML-escaped and this is display spoofing, NOT script injection (no XSS) - the correct weakness is CWE-345 (insufficient verification of data authenticity). This is a genuine low-priority hardening fix, not a high-urgency item. |
| Exploit ScenarioDerived | If the DataStore table UI resource is embedded in a context where an untrusted window or frame can reach it (a non-standard/incorrect host embedding), that frame sends a postMessage carrying fabricated fields/records; because the inbound listener never checks event.origin, the table renders attacker-supplied rows and phishing __link_url values that appear to originate from the queried CKAN portal, and can also spoof responses to the ui/initialize handshake. A working parent-spoof POC (poc/parent-spoof-poc.html) already demonstrates cross-origin row injection with no handshake. Factoring in AC:H and UI:R, exploitation requires both a mis-trusted embedding context and the user actually opening/viewing the panel. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 16, 2026
Content spoofing and MCP handshake interference in the ckan-mcp-server DataStore Table UI resource let any frame that can reach the embedded iframe inject fabricated table rows and spoof JSON-RPC responses, including the ui/initialize handshake. All npm versions of @aborruso/ckan-mcp-server before 0.4.112 are affected; the inbound message listener never validates event.origin and outbound postMessage calls use targetOrigin '*', although cell values are HTML-escaped so this is display spoofing rather than script execution. Exploitation requires the table UI to be embedded by a context other than the trusted MCP Apps host and to be actively viewed by the user, so real-world priority is low; publicly available exploit code exists in the advisory's proof-of-concept files, and no active exploitation has been reported.
RemediationAI
Upgrade @aborruso/ckan-mcp-server to 0.4.112 or later, the vendor-released fixed version identified in the advisory; no other patched release is referenced in the available data. If immediate upgrade is not possible, the highest-value compensating control is to constrain embedding of the DataStore Table UI so only the trusted MCP Apps host can frame it - for example by tightening the resource's frame-ancestors/CSP policy or by refusing to render the panel in non-standard hosts - accepting the trade-off that this can break legitimate third-party embedding scenarios. Where the resource is served or proxied, ensure only the trusted host origin is allowed to host the iframe and avoid exposing the panel to untrusted sibling or parent frames, and treat any table rows or link URLs produced in such a context as untrusted. For downstream fixes, the advisory's guidance is to validate event.origin against the expected host origin on every inbound message and drop messages from other origins, switch outbound postMessage calls from '*' to the explicit host origin established during ui/initialize, and optionally bind the channel to a nonce negotiated at initialize time so only the handshake partner can drive the panel; note that adopting a strict origin allowlist can cause the panel to stop responding if the host's origin differs from the configured value, so the expected origin should be derived from the negotiated handshake rather than hard-coded. Full details and the static and parent-spoof proof-of-concept scripts are in GHSA-vqff-r82h-9crc (https://github.com/ondata/ckan-mcp-server/security/advisories/GHSA-vqff-r82h-9crc).
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The affected component is the MCP Apps UI resource implemented in src/resources/datastore-table-ui.ts, an inline HTML/JavaScript panel that renders an interactive DataStore table inside the host application's webview or iframe and exchanges JSON-RPC 2.0 messages with its parent window over the browser postMessage API. Two protocol-level mistakes combine here: the inbound window 'message' listener consumes event.data without checking event.origin against an allowlist, and outbound calls use window.parent.postMessage(..., '*') with no fixed target origin. Because pending JSON-RPC requests are keyed by message id, an untrusted frame that can reach the document can resolve or reject requests (including the ui/initialize handshake) and feed arbitrary fields/records into initTable(), which renders attacker-controlled rows and link URLs. This is classified CWE-345, insufficient verification of data authenticity, at the message-channel level rather than a parser or memory-safety flaw; the escaping of rendered values means the tag 'XSS' is a mischaracterization and there is no code execution path. The affected package is the npm artifact @aborruso/ckan-mcp-server (CPE pkg:npm/@aborruso_ckan-mcp-server), and the security boundary that makes exploitation conditional is the MCP Apps host embedding model: a correctly implemented host makes the trusted parent the only reachable message source, whereas a non-standard or hostile parent/sibling frame removes that constraint.
Know when the next one hits your stack
- 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
AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N
AC:H and UI:R because exploitation needs a mis-trusted embedding plus the user viewing the panel; I:L added for content/handshake spoofing and C:L for leaked JSON-RPC; no availability impact.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
DescriptionGitHub Advisory
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
postMessageto 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: VULNERABLEpoc/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.originagainst the expected host origin on every inbound
message; drop messages from other origins.
- Send outbound
postMessagewith an explicit target origin (the host origin
established at initialize time) instead of '*'.
- Optionally, bind to a nonce/channel established during
ui/initializeso only
the negotiated host can drive the panel.
Threat Intelligence Overview
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.
GHSA-vqff-r82h-9crc
NVD
CVE.org
Exploit-DB