iframe sandbox attribute is really great to lock down the permissions
Given an iframe with an empty sandbox attribute (
<iframe sandbox src="..."> </iframe>), the framed document will be fully sandboxed, subjecting it to the following restrictions:
- The framed document is loaded into a unique origin, which means that all same-origin checks will fail; unique origins match no other origins ever, not even themselves. Among other impacts, this means that the document has no access to data stored in any origin’s cookies or any other storage mechanisms (DOM storage, Indexed DB, etc.).
- The framed document cannot create new windows or dialogs (via
target="_blank", for instance).
- Forms cannot be submitted.
- Plugins will not load.
- The framed document can only navigate itself, not its top-level parent. Setting
window.top.locationwill throw an exception, and clicking on link with
target="_top"will have no effect.
- Features that trigger automatically (autofocused form elements, autoplaying videos, etc.) are blocked.
- Pointer lock cannot be obtained.
seamlessattribute is ignored on
iframesthe framed document contains.
This is nicely draconian, and a document loaded into a fully sandboxed
iframe poses very little risk indeed. Of course, it also can’t do much of value: you might be able to get away with a full sandbox for some static content, but most of the time you’ll want to loosen things up a bit.
With the exception of plugins, each of these restrictions can be lifted by adding a flag to the sandbox attribute’s value. Sandboxed documents can never run plugins, as plugins are unsandboxed native code, but everything else is fair game:
allow-formsallows form submission.
allow-popupsallows popups (
allow-pointer-lockallows (surprise!) pointer lock.
allow-same-originallows the document to maintain its origin; pages loaded from
https://example.com/will retain access to that origin’s data.
allow-top-navigationallows the document to break out of the frame by navigating the top-level window.
One important thing to note is that the sandboxing flags applied to a frame also apply to any windows or frames created in the sandbox. This means that we have to add
allow-forms to the frame’s sandbox, even though the form only exists in the window that the frame pops up.
sandbox attribute in place, the widget gets only the permissions it requires, and capabilities like plugins, top navigation, and pointer lock remain blocked. We’ve reduced the risk of embedding the widget, with no ill-effects. It’s a win for everyone concerned.