iframe Sandbox and Security
Embed third-party content safely — sandbox tokens, allow attributes, CSP frame-src, and postMessage boundaries.
- html
- iframe
- security
- sandbox
<iframe> embeds another browsing context. That is power and risk: the framed page can be a trusted payment widget or a hostile script host. sandbox, allow, and CSP frame-src are how you shrink the blast radius.
Docs: MDN <iframe>, sandbox, CSP frame-src.
Default risks
Without restrictions, a framed document may:
- Run scripts
- Submit forms
- Navigate top-level page (depending on conditions)
- Access storage for its origin
- Open popups
Same-origin iframes can be scripted by the parent; cross-origin ones cannot access the parent DOM (SOP), but still participate in clickjacking and UI redress unless mitigated.
sandbox attribute
<iframe
title="Calendar embed"
src="https://calendar.example.com/embed/abc"
sandbox="allow-scripts allow-same-origin allow-popups"
></iframe>
Empty sandbox applies maximum restrictions (no scripts, no forms, unique opaque origin, etc.).
| Token | Allows |
|---|---|
allow-scripts |
JavaScript |
allow-same-origin |
Treat as real origin (storage, etc.) |
allow-forms |
Form submission |
allow-popups |
window.open |
allow-popups-to-escape-sandbox |
Opened windows not sandboxed |
allow-top-navigation |
Navigate top browsing context |
allow-top-navigation-by-user-activation |
Safer top nav |
allow-downloads |
Downloads |
allow-modals |
alert/confirm |
Dangerous combo: allow-scripts + allow-same-origin on untrusted content can let the frame remove sandboxing via script in some historical scenarios — treat untrusted + both flags as high risk. Prefer minimal tokens.
Permissions policy via allow
<iframe
title="YouTube video"
src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin"
></iframe>
allow gates features (camera, mic, payment, etc.) even when scripts run.
Always title iframes
<iframe title="Payment form" src="…"></iframe>
Screen readers announce iframes; empty titles fail a11y checks.
postMessage boundary
// parent
iframe.contentWindow.postMessage({ type: "INIT" }, "https://widget.example.com");
window.addEventListener("message", (event) => {
if (event.origin !== "https://widget.example.com") return;
// handle event.data
});
Validate origin and message shape. Never trust event.data blindly.
CSP and cookies
Content-Security-Policy: frame-src https://widget.example.com; frame-ancestors 'self'
frame-src— who you may embedframe-ancestors— who may embed you (clickjacking defense; alsoX-Frame-Options)
Interview out-loud
“Iframes embed separate documents. I set a descriptive title, use sandbox with least privilege, gate features with allow, restrict sources via CSP frame-src, and only accept postMessage from expected origins. allow-scripts combined with allow-same-origin on untrusted content is a red flag.”
Footguns
- Sandbox-free third-party embeds.
- Missing iframe titles.
- Trusting postMessage without origin checks.
- Using iframes for seamless same-app routing when components would do.
- Clickjacking your own authenticated UI without frame-ancestors.
Least-privilege embeds
<!-- Static map preview: no scripts needed -->
<iframe
title="Office location map"
src="https://maps.example.com/static-embed/…"
sandbox=""
loading="lazy"
referrerpolicy="no-referrer"
></iframe>
Start from empty sandbox and add tokens only when the embed breaks for a documented reason. Log those reasons in code comments so future you does not “fix” it by removing sandbox entirely.
Clickjacking your own app
If your authenticated UI can be framed by an attacker origin, users may be tricked into clicking “Delete” under a fake overlay. Set Content-Security-Policy: frame-ancestors 'self' (or a strict allowlist) and consider X-Frame-Options for legacy. Combine with cookie SameSite practices. Sandbox protects embeds you host; frame-ancestors protects you from being embedded.
Related
Further reading
Related guides
- Accessibility Tree OverviewHow browsers build the accessibility tree from DOM and CSS — roles, names, states, what’s pruned, and how to inspect it in DevTools.
- Audio and Video ElementsNative audio/video — controls, sources, captions, autoplay policies, and accessibility requirements for media on the web.
- Autocomplete and Name Attributesname and autocomplete on form fields — password managers, autofill tokens, and why missing names break real users more than demos.
- Base Element and Relative URLsHow <base href> rewrites relative URLs for links, scripts, and forms — powerful for static hosts, dangerous when set accidentally.
- contenteditable Basicscontenteditable surfaces — what the browser gives you, sanitization, keyboard and a11y gaps, and when to pick a real editor library.