You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/pentesting-web/postmessage-vulnerabilities/README.md
+38Lines changed: 38 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -247,6 +247,43 @@ For **more information**:
247
247
- Link to page about [**XSS**](../xss-cross-site-scripting/index.html)
248
248
- Link to page about [**client side prototype pollution to XSS**](../deserialization/nodejs-proto-prototype-pollution/index.html#client-side-prototype-pollution-to-xss)
249
249
250
+
### Trusted-origin allowlist isn't a boundary
251
+
252
+
A strict `event.origin` check only works if the **trusted origin cannot run attacker JS**. When privileged pages embed third-party iframes and assume `event.origin === "https://partner.com"` is safe, any XSS in `partner.com` becomes a bridge into the parent:
253
+
254
+
```javascript
255
+
// Parent (trusted page)
256
+
window.addEventListener("message", (e) => {
257
+
if (e.origin!=="https://partner.com") return
258
+
const [type, html] =e.data.split("|")
259
+
if (type ==="Partner.learnMore") target.innerHTML= html // DOM XSS
260
+
})
261
+
```
262
+
263
+
Attack pattern observed in the wild:
264
+
265
+
1.**Exploit XSS in the partner iframe** and drop a relay gadget so any `postMessage` becomes code exec inside the trusted origin:
2.**From the attacker page**, send JS to the compromised iframe that forwards an allowed message type back to the parent. The message originates from `partner.com`, passes the allowlist, and carries HTML that is inserted unsafely:
3. The parent injects the attacker HTML, giving **JS execution in the parent origin** (e.g., `facebook.com`), which can then be used to steal OAuth codes or pivot to full account takeover flows.
280
+
281
+
Key takeaways:
282
+
283
+
-**Partner origin isn't a boundary**: any XSS in a "trusted" partner lets attackers send allowed messages that bypass `event.origin` checks.
284
+
- Handlers that **render partner-controlled payloads** (e.g., `innerHTML` on specific message types) make partner compromise a same-origin DOM XSS.
285
+
- A wide **message surface** (many types, no structure validation) gives more gadgets for pivoting once a partner iframe is compromised.
286
+
250
287
### Predicting **`Math.random()`** callback tokens in postMessage bridges
251
288
252
289
When message validation uses a “shared secret” generated with `Math.random()` (e.g., `guid() { return "f" + (Math.random() * (1<<30)).toString(16).replace(".", "") }`) and the same helper also names plugin iframes, you can recover PRNG outputs and forge trusted messages:
@@ -277,6 +314,7 @@ iframe.location = fbMsg // sends postMessage from facebook.com with forged callb
-[Leaking fbevents: OAuth code exfiltration via postMessage trust leading to Instagram ATO](https://ysamm.com/uncategorized/2026/01/16/leaking-fbevents-ato.html)
279
316
- To practice: [https://github.com/yavolo/eventlistener-xss-recon](https://github.com/yavolo/eventlistener-xss-recon)
0 commit comments