---
id: CVE-2026-76894
aliases:
  - GHSA-vqff-r82h-9crc
title: >-
  ckan-mcp-server: DataStore Table UI resource does not validate postMessage
  origin (in) and posts to targetOrigin "*" (out)
summary: >-
  ckan-mcp-server: DataStore Table UI resource does not validate postMessage
  origin (in) and posts to targetOrigin "*" (out)
severity: low
cvss: 3.1
cwe:
  - CWE-345
  - CWE-940
vendor: aborruso
product: '@aborruso/ckan-mcp-server'
ecosystem: npm
affected:
  - '@aborruso/ckan-mcp-server < 0.4.112'
patched:
  - '@aborruso/ckan-mcp-server 0.4.112'
published: '2026-10-16'
updated: '2026-10-16'
sourceUpdated: '2026-10-16T19:24:46Z'
source: GHSA
sourceUrl: 'https://github.com/advisories/GHSA-vqff-r82h-9crc'
references:
  - url: >-
      https://github.com/ondata/ckan-mcp-server/security/advisories/GHSA-vqff-r82h-9crc
  - url: 'https://github.com/advisories/GHSA-vqff-r82h-9crc'
tags:
  - ghsa
  - npm
ingestedAt: '2026-10-16T19:46:24.283Z'
---

## Overview

## 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):

```js
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.

## Affected packages

- `@aborruso/ckan-mcp-server < 0.4.112`

## Remediation

Upgrade to a patched release:

- `@aborruso/ckan-mcp-server 0.4.112`
