how to prevent iframe from accessing parent frame

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:

  • JavaScript will not execute in the framed document. This not only includes JavaScript explicitly loaded via script tags, but also inline event handlers and javascript: URLs. This also means that content contained in noscript tags will be displayed, exactly as though the user had disabled script herself.
  • 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 or 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 will 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.
  • The seamless attribute is ignored on iframes the 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-forms allows form submission.
  • allow-popups allows popups (, showModalDialog(), target=”_blank”, etc.).
  • allow-pointer-lock allows (surprise!) pointer lock.
  • allow-same-origin allows the document to maintain its origin; pages loaded from will retain access to that origin’s data.
  • allow-scripts allows JavaScript execution, and also allows features to trigger automatically (as they’d be trivial to implement via JavaScript).
  • allow-top-navigation allows 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.

With the 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.