Skip to content

sandbox

sandbox applies the same restrictions to the response as the <iframe sandbox> attribute does to an embedded document: no scripts, no forms, no popups, and an opaque origin, until you grant each capability back by token.

It is the odd directive out. It takes tokens rather than sources, it is not allowed in a <meta> tag, and - the part that catches people - it is ignored in a report-only policy. You cannot trial it the way you trial the rest of CSP.

Content-Security-Policy: sandbox;
Content-Security-Policy: sandbox <token> <token>;
  • Script execution, unless allow-scripts is granted.
  • Form submission, unless allow-forms is granted.
  • Popups, unless allow-popups is granted.
  • Modal dialogs - alert(), confirm(), prompt(), print() - unless allow-modals is granted.
  • Top-level navigation, unless allow-top-navigation or allow-top-navigation-by-user-activation is granted.
  • The document’s origin: without allow-same-origin the response gets an opaque origin, which means no cookies, no localStorage, and no same-origin access to anything.
  • Anything at all when sent on Content-Security-Policy-Report-Only. The directive is ignored there.
  • Anything at all in a <meta http-equiv> policy. Header only.

sandbox has no fallback and takes tokens rather than sources. It applies only when written, only on an enforcing header, and only from an HTTP response - not from a <meta> tag.

Content-Security-Policy: sandbox
  • Start with no tokens and grant back only what the response needs. There is no useful default token set - the right one is entirely specific to what the response is for.
  • Reach for sandbox on user-uploaded content, previews and untrusted HTML you have to serve from your own origin, not on your application’s own pages.
  • Do not grant allow-scripts and allow-same-origin together on untrusted content. Between them they let the document reach its own sandbox and remove it, which leaves you with the syntax of a sandbox and none of the effect.

Serving an uploaded HTML preview with scripts off and an opaque origin:

Content-Security-Policy: sandbox; default-src 'none'

Under a bare sandbox, every one of these is refused:

<script>
init();
</script>
<form action="/submit" method="post"></form>
<a href="https://example.com" target="_blank">Open</a>
  • Widely available across browsers since November 2016.
  • Not supported in <meta> elements or in Content-Security-Policy-Report-Only. A report-only rollout will tell you nothing about what this directive would break.
  • sandbox produces no violation reports, so it never appears as a directive in HeaderHawk.
  • The directive is ignored in report-only policies, so the usual way of finding out what a directive would break does not work here. Test it on a staging response in enforce mode instead.
  • In enforce mode a sandbox restriction surfaces as a console error rather than as the kind of resource-blocked report that reaches a reporting endpoint.
  • HeaderHawk’s normalizer does recognise sandbox as a directive name, so a report naming it would be filed under sandbox rather than under default-src - but no browser sends one, so the facet stays empty.

Point your policy’s report-uri at your site’s HeaderHawk endpoint and the violations above arrive in the dashboard, grouped as described. The Quick Start sets that up in five minutes, and the integration guides cover the header syntax for each platform.