Advanced iframe: Sandbox & Security
Master the sandbox attribute, allow attribute, and security considerations for embedding third-party content safely in iframes.
Overview
Key Points
- •`sandbox` with no value applies all restrictions; add capabilities individually
- •`allow-scripts` enables JS execution in the frame
- •`allow-same-origin` lets the frame access its origin's cookies/storage (NEVER combine with allow-scripts)
- •`allow-forms` enables form submission; `allow-popups` enables window.open()
- •`allow-top-navigation` lets the frame navigate the parent window (dangerous in ads)
- •`srcdoc` attribute embed inline HTML directly without a URL (runs in about:blank, no same-origin access)
- •`referrerpolicy="no-referrer"` prevents the Referer header from leaking your URL to embedded content
Examples
Secure embedding of third-party content
<!-- Embed a user-provided HTML snippet safely -->
<!-- srcdoc is treated as same-origin to about:blank no access to your site -->
<iframe
srcdoc="<h1>User Content</h1><p>Hello World</p>"
sandbox="allow-scripts"
width="600"
height="300"
title="User content preview"
></iframe>
<!-- Embed a payment widget with minimal permissions -->
<iframe
src="https://payment.provider.com/widget"
sandbox="allow-scripts allow-forms allow-same-origin allow-popups"
allow="payment"
referrerpolicy="no-referrer-when-downgrade"
width="400"
height="200"
title="Payment form"
></iframe>
<!-- Embed an advertisement with strict sandbox -->
<iframe
src="https://ads.network.com/banner"
sandbox="allow-scripts allow-popups"
allow="autoplay 'none'"
referrerpolicy="no-referrer"
loading="lazy"
title="Advertisement"
></iframe>For ads: no allow-same-origin (can't access your cookies), no allow-top-navigation (can't hijack your page).
The sandbox allow-same-origin + allow-scripts security hole
<!--
⚠️ CRITICAL SECURITY WARNING ⚠️
NEVER do this with content you don't fully trust:
-->
<!--
When combined, the embedded page can:
1. Run JS (allow-scripts)
2. Treat itself as same-origin to your site (allow-same-origin)
3. Therefore: modify its own sandbox attribute and REMOVE IT ENTIRELY
4. Then run unrestricted same-origin JS on your site
Example attack: sandbox="allow-scripts allow-same-origin"
-> embedded JS does: frameElement.removeAttribute('sandbox');
-> Now it can read your localStorage, make requests as the user, etc.
-->
<!-- ✅ CORRECT patterns: -->
<!-- Only scripts, no same-origin access (for CDN widgets) -->
<iframe src="..." sandbox="allow-scripts"></iframe>
<!-- Only same-origin (for trusted sub-apps, no additional JS needed) -->
<iframe src="/app-module" sandbox="allow-same-origin allow-forms"></iframe>This combination is one of the most dangerous HTML security mistakes.
postMessage communication between parent and iframe
<!-- parent.html -->
<iframe id="child" src="/child.html" sandbox="allow-scripts"></iframe>
<script>
const frame = document.getElementById('child');
// Send message to iframe
frame.contentWindow.postMessage(
{ type: 'INIT', data: { userId: 42 } },
'https://yoursite.com' // target origin specify exactly, never use '*' with sensitive data
);
// Receive message from iframe
window.addEventListener('message', (event) => {
// ALWAYS verify origin before processing
if (event.origin !== 'https://yoursite.com') return;
console.log('Received from iframe:', event.data);
});
</script>
<!-- child.html (inside the iframe) -->
<script>
// Receive message from parent
window.addEventListener('message', (event) => {
if (event.origin !== 'https://yoursite.com') return;
console.log('Parent says:', event.data);
// Reply to parent
window.parent.postMessage({ type: 'READY' }, event.origin);
});
</script>Always verify event.origin in message handlers never use "*" for sensitive communication.
Common Mistakes
- Combining sandbox="allow-scripts allow-same-origin" on untrusted content the iframe can remove its own sandbox
- Using postMessage with targetOrigin="*" for sensitive data any page can receive the message
- Not adding sandbox at all to embedded ads or third-party widgets they can navigate your page, steal focus, or access your cookies
Note
The `csp` attribute on iframes (still experimental in some browsers) lets you impose a Content Security Policy on the embedded frame: `<iframe csp="script-src 'none'">` this adds another layer of protection on top of sandbox.
Exercises
Write HTML to solve each exercise. Use Preview to see it render in a live iframe, then mark as done.
Completed: 0 / 5 exercises
Knowledge Check
Question 1 of 4