Engineering Journal
Schema Editor
Schema Editor

Postmortem: We Shipped postMessage('*') Because It Worked and We Didn't Think About Who Else Would Receive It

2026-06-04

TLDR

During a security review of our VS Code webview editor, an audit flagged five postMessage invocations utilizing '' target origins. The wildcard argument had been copied from early tutorial examples and worked without issue during development. However, passing '' allowed any embedding frame to inspect outgoing messages. We replaced all wildcard targets with window.location.origin and routed all messaging through a centralized CwsBridge module.
Audit MilestonePre-Audit Wildcard ImplementationPost-Audit Bridge Architecture
Outbound Target Origin'*' (Delivers to any domain)window.location.origin
Inbound Event HandlerUnfiltered addEventListenerStrict origin verification guard
Code StructureAd-hoc postMessage calls across 5 filesCentralized CwsBridge utility module

Problem statement: the origin of copy-pasted wildcards

Our editor runs inside a VS Code webview iframe.

During initial development, we implemented cross-frame communication using standard postMessage snippets copied from online documentation:

// DEPRECATED: Initial tutorial-copied postMessage calls
window.parent.postMessage({ type: 'cws:ready' }, '*');
window.parent.postMessage({ type: 'tool:state', payload: canvasState }, '*');

Because the code worked smoothly inside VS Code, the wildcard origins remained unnoticed until a formal security audit.


Technical failure mode: auditing open broadcast channels

The security audit identified two major concerns:

  1. Unbounded Receiver Audience: Passing '*' meant any webpage embedding the tool could receive state broadcasts.
  2. Future Escalation Risk: As developers added user state or document payload attributes to canvasState, the open channel would expose sensitive data without warning.

The fix & architecture: centralized bridge module

We removed all ad-hoc postMessage calls across the codebase and created a single CwsBridge utility module to manage cross-frame transport:

// REFACTORED: Centralized Secure Messaging Bridge (CwsBridge.js)
export const CwsBridge = {
  targetOrigin: window.location.origin,

send(type, payload) { try { window.parent.postMessage({ type, payload }, this.targetOrigin); } catch (err) { console.error('Bridge postMessage failed:', err); } },

onData(handler) { window.addEventListener('message', (e) => { // Validate origin against expected same-origin or VS Code webview scheme if (e.origin !== this.targetOrigin && !e.origin.startsWith('vscode-webview://')) { return; } handler(e.data); }); } };

All feature components now communicate via CwsBridge.send('tool:state', payload), guaranteeing target origin enforcement across the entire application.

Rule of thumb: Encapsulate all cross-frame messaging inside a single bridge module that enforces target origin boundaries automatically.
Read this post in the full Engineering Journal →