Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/pentesting-web/xss-cross-site-scripting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,35 @@ function handleResponse() {
</script>
```

### PostMessage-origin script loaders (opener-gated)

If a page **stores `event.origin` from a `postMessage` and later concatenates it into a script URL**, the sender controls the **origin** of the loaded JS:

```javascript
window.addEventListener('message', (event) => {
if (event.data.msg_type === 'IWL_BOOTSTRAP') {
localStorage.setItem('CFG', {host: event.origin, pixelID: event.data.pixel_id});
startIWL(); // later loads `${host}/sdk/${pixelID}/iwl.js`
}
});
```

Exploitation recipe (from CAPIG):

- **Gates**: fires only when `window.opener` exists and `pixel_id` is allowlisted; **origin is never checked**.
- **Use CSP-allowed origin**: pivot to a domain already permitted by the victim CSP (e.g., logged-out help pages allowing analytics like `*.THIRD-PARTY.com`) and host `/sdk/<pixel_id>/iwl.js` there via takeover/XSS/upload.
- **Restore `opener`**: in Android WebView, `window.name='x'; window.open(target,'x')` makes the page its own opener; send the malicious `postMessage` from a hijacked iframe.
- **Trigger**: the iframe posts `{msg_type:'IWL_BOOTSTRAP', pixel_id:<allowed>}`; the parent then loads attacker `iwl.js` from the CSP-allowed origin and runs it.

This turns origin-less `postMessage` validation into a **remote script loader primitive** that survives CSP if you can land on any origin already allowed by the policy.

### Supply-chain stored XSS via backend JS concatenation

When a backend **builds a shared SDK by concatenating JS strings with user-controlled values**, any quote/structure breaker can inject script that is served to every consumer:

- Example pattern (Meta CAPIG): server appends `cbq.config.set("<pixel>","IWLParameters",{params: <user JSON>});` directly into `capig-events.js`.
- Injecting `'` or `"]}` closes the literal/object and adds attacker JS, creating **stored XSS** in the distributed SDK for every site that loads it (first-party and third-party).

### Abusing Service Workers


Expand Down Expand Up @@ -2006,5 +2035,6 @@ other-js-tricks.md
- [HackerOne Report #2902856 - Nextcloud Mail List-Unsubscribe SSRF](https://hackerone.com/reports/2902856)
- [From "Low-Impact" RXSS to Credential Stealer: A JS-in-JS Walkthrough](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html)
- [MDN eval()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)
- [CAPIG XSS: postMessage origin trust becomes a script loader + backend JS concatenation enables supply-chain stored XSS](https://ysamm.com/uncategorized/2026/01/13/capig-xss.html)

{{#include ../../banners/hacktricks-training.md}}