An empty sandbox attribute locks an iframe down hard: no scripts, no form submission, no popups, no alerts and an opaque origin that fails every same-origin check. Each allow- token you add gives one power back. Toggle the tokens below to see exactly what breaks, then copy the smallest set your embed needs.
| Embedding | Suggested sandbox value |
|---|---|
| Static HTML preview you generated | sandbox (empty) |
| Interactive demo or code playground output | sandbox="allow-scripts" |
| Third-party form that posts its answers | sandbox="allow-scripts allow-forms allow-same-origin" (only for a different origin) |
| Widget with links that open in a new tab | add allow-popups allow-popups-to-escape-sandbox |
| Game that captures the mouse | add allow-pointer-lock |
Updated
The sandbox attribute is the cheapest security win you can add to an iframe that shows content you did not write: user HTML, an ad slot, a preview of a generated page. The hard part is knowing which tokens a given embed needs, because a missing one usually fails silently. The live frame below runs real tests, so you can see each failure instead of guessing. For the basics of embedding, start with our HTML iframe and video guide.
The frame below is a srcdoc document. allow-same-origin is not offered here, because a srcdoc frame would then share this page's origin, the exact pairing the tips warn about.
Tokens
Current attribute
sandbox=""Scripts are blocked, so nothing in this frame can run.
Tokens are space separated and case insensitive. Anything not listed stays blocked.
| Token | Allows |
|---|---|
| allow-scripts | Run scripts, but not open popup windows |
| allow-same-origin | Keep the document's real origin instead of an opaque one |
| allow-forms | Submit forms (otherwise they render but send nothing) |
| allow-modals | Use alert(), confirm(), print() and prompt() |
| allow-popups | Open windows with window.open() or target="_blank" |
| allow-popups-to-escape-sandbox | Let those new windows open without the sandbox |
| allow-downloads | Download files from links or navigation |
| allow-top-navigation | Navigate the top-level page |
| allow-top-navigation-by-user-activation | Navigate the top-level page, only after a click |
| allow-top-navigation-to-custom-protocols | Open non-http protocols such as mailto: |
| allow-pointer-lock | Use the Pointer Lock API |
| allow-orientation-lock | Lock the screen orientation |
| allow-presentation | Start a presentation session |
| allow-storage-access-by-user-activation | Request unpartitioned cookies through the Storage Access API |
The button inside the frame has an onclick handler, but with an empty sandbox it never runs.
<iframe sandbox title="Preview of the submitted page" style="width:100%;height:90px;border:1px solid #cbd5e1"
srcdoc="<p>Hello from the preview.</p><button onclick="this.textContent='Ran'">Press me</button>"></iframe>The widget runs its own script and posts its form, and links can open real tabs. It cannot redirect your page.
<iframe
src="https://widgets.example.net/signup"
title="Newsletter sign-up form"
sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"
loading="lazy"
width="400" height="320"></iframe>A server can sandbox its own page with CSP, which applies even when the page is opened directly rather than framed.
Content-Security-Policy: sandbox allow-scripts allow-forms
Without allow-same-origin, the framed document gets a special origin that always fails the same-origin policy. Its self.origin reads as the string "null".
That one rule switches off a lot, because the framed page no longer counts as part of its own site. Widgets that depend on their own cookies or saved state often break here, which is why so many ask for allow-same-origin.
A blocked popup does not throw; window.open simply returns null. A blocked alert returns straight away without showing anything. A blocked form just sits there. When an embed misbehaves, check the browser console for the frame before blaming the embed's own code.
That is why the demo on this page reports results inside the frame: you see the same quiet behaviour a real embed would hit.
sandbox limits what the framed document may do. The allow attribute sets a permissions policy for features such as camera, fullscreen or geolocation. Content-Security-Policy, sent by the framed page's server, limits which scripts and resources it loads.
A careful embed of untrusted content uses all three, and the frame-ancestors part of CSP decides the reverse question: who may frame a page at all.
It applies every restriction at once. The framed document cannot run scripts, submit forms, open popups or modals, navigate the top window, lock the pointer or orientation, start downloads, and it is treated as coming from a unique origin that never matches anyone.
When the framed document is on the same origin as your page, those two tokens together let its script reach up and delete the sandbox attribute, so it ends up no safer than an ordinary iframe. The pairing is fine for content from a genuinely different origin, which cannot touch your page anyway.
Without allow-forms the form still renders, but submitting it triggers no validation and sends no data to a server. Add allow-forms. If the form also relies on cookies or storage from its own site, it will need allow-same-origin too.
Not unless you add allow-top-navigation, or allow-top-navigation-by-user-activation, which only permits it after the person clicks inside the frame. Leaving both out stops an embed from replacing your page with another site.
It is the main layer, not the only one. Serve untrusted content from a separate origin or srcdoc, keep allow-same-origin off when scripts are on, and add a Content-Security-Policy to the framed document if you control how it is served.
Related: HTML iframe and video guide, Fix iframe refused to connect, iframe generator, CORS explained.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.