Should I use a header or a meta tag?
A response header. A meta tag cannot carry frame-ancestors, reporting, or Report-Only, and it only applies to content after it. Use the meta tag only when you cannot set headers.
Header or meta tag.
Start from a strict policy, adjust each directive, add a nonce or script hashes, and copy a header that does what you meant. Warnings explain every weak spot as you type.
Loading the toolbox.
You do not have to take our word that your data stays here. Developer tools show every request a page makes, so you can watch this page work and confirm that nothing is sent. The check takes under a minute.
F12, or Cmd+Option+I on a Mac, and select the Network tab.Only two things can add a line to that log, and neither carries your data. Submitting the feedback form sends the vote and comment you typed. Typing characters in a script the page has not displayed yet, such as Cyrillic or Greek, can make the browser fetch the matching font file, and that request names only the font.
The production site also sends a Content-Security-Policy header that tells your browser to refuse connections to anywhere except this site and the anonymous analytics endpoint, so a coding mistake could not quietly send your data elsewhere.
A Content-Security-Policy, or CSP, is a response header that tells the browser where a page may load scripts, styles, images, and other resources from, and where it may send data. If an attacker manages to inject a script tag through a cross-site scripting bug, a good CSP stops the browser from running it. It is the most effective second line of defense against XSS.
A policy is a list of directives separated by semicolons. Each directive names a resource type and lists the allowed sources, such as 'self', a host like https://cdn.example.com, a scheme like https:, or a nonce or hash.
'unsafe-inline'.Keywords typed without quotes, such as self, are quoted automatically with a warning, because unquoted they are read as host names. Semicolons, commas, and line breaks are stripped from every value so a pasted source cannot inject a directive.
Use a nonce when your server renders HTML per request: generate a fresh random value for every response, put it in the header as 'nonce-VALUE', and add nonce="VALUE" to each script tag you trust. A fixed nonce in a static file protects nothing. Use a hash for a static inline script: the SHA-256 of its exact text, base64 encoded, allows that script and only that script.
Add 'strict-dynamic' to let a trusted script load further scripts, which is how most bundlers and tag managers work. Modern browsers then ignore host allowlists in script-src, which is the point: a nonce-based strict policy cannot be bypassed through an allowlisted CDN.
Content-Security-Policy-Report-Only with a report endpoint, and browse every part of the site.Content-Security-Policy to enforce it.Elsewhere in the toolbox: 2hash, 2base, 2otp, 2xml, and more on the 2toolbox home page. Part of the 2suite.io privacy-first ecosystem.
A response header. A meta tag cannot carry frame-ancestors, reporting, or Report-Only, and it only applies to content after it. Use the meta tag only when you cannot set headers.
Without unsafe-inline, a CSP blocks inline script by design. Allow specific scripts with a nonce or hash rather than re-opening unsafe-inline.
frame-ancestors supersedes it in modern browsers. Sending both is harmless and covers very old browsers.
It shows the format only. A real nonce must be generated by your server, freshly for each response.