# Xs Leaks

> XS-Leaks — cross-site information leaks via timing, frame counting, navigation, error oracles. Side-channel attacks against same-origin authenticated state.

- Skill: `purpleailab/xs-leaks` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/xs-leaks`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/xs-leaks/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/xs-leaks

---


# XS-Leaks (Cross-Site Leaks)

XS-Leaks abuse browser primitives that leak information ACROSS origins.
Attacker page can observe whether a cross-origin GET returned different
content based on victim's authenticated state. Smaller than full
cross-origin read (which is blocked), but enough to enumerate identifiers,
detect membership, learn search-result presence.

## 1. Categories

### 1.1 Timing oracles
Cross-origin fetch / image load timing varies by server response size.
Attacker measures load time → infers content.
```javascript
const start = performance.now();
const img = new Image();
img.onerror = () => console.log(performance.now() - start);
img.src = 'https://target.com/api/users/me/notifications';
```

### 1.2 Frame counting (`window.frames.length`)
Some pages embed N iframes when authenticated and 0 when not. Attacker
iframes target page and reads `iframe.contentWindow.frames.length`.

### 1.3 Window name / postMessage leak
`iframe.contentWindow.name` is preserved across navigation. Some pages
set it w/ user-identifying data.

### 1.4 Error-event oracle
`<img src=target.com/api/user/{id}/data>` triggers different `onerror`
behavior based on response code (403 vs 404 vs 200 w/ image content-type).

### 1.5 CSS injection style oracle
`<link rel=stylesheet href=target.com/page>` — different applied styles
leak state via getComputedStyle of attacker page.

### 1.6 Search result presence
Many search endpoints return cached/non-cached headers indicating hits.
Attacker measures cache hit vs miss timing for guessed search terms.

### 1.7 ID guessability (XS-Search)
```javascript
for (const guessed_id of guessable_set) {
    const url = `https://target.com/api/user/${guessed_id}`;
    // measure timing or frame-count differential
}
```

## 2. xsleaks.dev — canonical reference

Full taxonomy + browser-version compatibility matrix:
https://xsleaks.dev/

Decepticon agents should consult this for current technique viability —
browser mitigations evolve fast (COOP, COEP, Cross-Origin-Opener-Policy).

## 3. Detection

```javascript
// Frame count
const f = document.createElement('iframe');
f.src = 'https://target.com/dashboard';   // attacker hosts this in own page
document.body.appendChild(f);
f.onload = () => {
    console.log('frames:', f.contentWindow.frames.length);
};

// Timing
async function timeFetch(url) {
    const t = performance.now();
    try { await fetch(url, {mode:'no-cors', credentials:'include'}); } catch {}
    return performance.now() - t;
}
```

## 4. PoC framing

XS-Leak PoCs require:
- Attacker host (your own controlled domain)
- Victim browser with authenticated session to target
- Visual demonstration of leaked info (e.g. infer victim's email, search history, friend list)

Document the attack page, record video of victim browser visiting it →
inferred information displayed.

## 5. Severity

| Bug | Severity |
|---|---|
| XS-Search enumerating victim's private documents | High 7-8 |
| Frame-count revealing logged-in state | Medium 5-6 |
| Timing oracle inferring victim email / ID | High 7-8 |
| Window.name leaking session info | High 7-8 |
| Cross-origin error-event leaking which users exist | Medium 4-5 |

## 6. Defender

- Set `Cross-Origin-Opener-Policy: same-origin`
- Set `Cross-Origin-Embedder-Policy: require-corp`
- Set `Cross-Origin-Resource-Policy: same-origin`
- Disable iframe embedding for sensitive pages: `X-Frame-Options: DENY` or `frame-ancestors 'none'` in CSP
- Constant-time responses for sensitive endpoints (esp. when state-dependent)
- `Vary: Cookie` + careful caching

## Cross-references
- Upstream: `skills/_corpus/payloads/XS-Leak/`
- xsleaks.dev — primary reference
- DOM clobbering overlap (different class, same client-side mindset): `skills/exploit/web/dom-clobbering/SKILL.md`

