Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy PostMessage Security
Advanced · 20 min

PostMessage Security

Learn how insecure postMessage handlers without origin validation enable cross-origin data theft and XSS.

1 Insecure postMessage Handlers

window.postMessage is used for cross-origin communication between frames and windows. Missing origin validation and unsafe data handling create serious vulnerabilities.

Missing origin check:

// VULNERABLE: no origin validation
window.addEventListener("message", (event) => {
  // Any window can send messages — including attackers!
  const data = JSON.parse(event.data);
  if (data.action === "setUserData") {
    updateProfile(data.payload);
  }
});

Unsafe data handling with eval:

// VULNERABLE: executing received code
window.addEventListener("message", (event) => {
  eval(event.data);  // Arbitrary code execution from any origin!
});

Attack scenario:

// Attacker's page
targetWindow.postMessage(
  JSON.stringify({ action: "setUserData", payload: { email: "[email protected]" } }),
  "*"  // Sends to victim window regardless of origin
);

2 Validate Origin and Use Structured Data

Always validate event.origin against an allowlist before processing received messages, and never use eval or innerHTML with message data.

Safe message handler:

const ALLOWED_ORIGINS = new Set([
  "https://parent-app.com",
  "https://www.parent-app.com"
]);

window.addEventListener("message", (event) => {
  // ALWAYS validate origin first
  if (!ALLOWED_ORIGINS.has(event.origin)) {
    console.warn("Rejected message from:", event.origin);
    return;
  }

  // Use structured data — avoid eval and innerHTML
  if (typeof event.data !== "object" || event.data === null) return;

  const { action, payload } = event.data;
  switch (action) {
    case "updateTheme":
      if (typeof payload.theme === "string") {
        applyTheme(payload.theme);
      }
      break;
    // Only handle explicitly expected actions
  }
});

Sending messages to specific origins:

// Always specify target origin — never use "*" with sensitive data
childFrame.contentWindow.postMessage(
  { action: "setToken", token: authToken },
  "https://trusted-frame.com"  // Target origin
);

Knowledge Check

0/3 correct
Q1

What happens when a postMessage handler does not validate event.origin?

Q2

Why should you never pass "*" as the targetOrigin when sending sensitive data?

Q3

What is the safest data type to pass via postMessage?

Code Exercise

Add Origin Validation to postMessage Handler

The message handler processes messages from any origin. Add origin validation to only accept messages from "https://parent-app.com".

javascript