How to add a Content-Security-Policy
A CSP tells browsers which scripts, styles and frames may load, and blocks most cross-site scripting even when a plugin has a hole.
Step by step, with screenshots: Subresource Integrity for third-party scripts: help and harm →
Check your own site
Runs these 2 checks and the other 191, free, in about 45 seconds.
Or run only this check with the free Mobile-friendly test + CSP generator or the free Security headers checker.
What it is
A Content-Security-Policy (CSP) is a response header that tells the browser which sources of scripts, styles, images, frames and other content a page may use. Anything not on the list is blocked, so a script injected through a vulnerable plugin or form field cannot run.
CSP is the strongest browser-side defence against cross-site scripting, one of the injection attacks in the OWASP Top 10. getReport flags pages without any CSP, and policies whose script-src still allows 'unsafe-inline', 'unsafe-eval' or a * wildcard, since those let injected scripts run. A strong policy allows scripts by nonce or hash, and sets object-src 'none' and base-uri 'none'.
What a passing site looks like
- Content-Security-Policy header is setwarning · −6 ptseffort M
- Content-Security-Policy blocks inline and wildcard scriptswarning · −2 ptseffort M
1. Content-Security-Policy header is missing
Why it matters. A CSP blocks most cross-site scripting attacks by listing where scripts may load from. Without one, a single injected script can steal sessions or card data.
- Start in report-only mode with Content-Security-Policy-Report-Only to see what would break.
- Move to an enforcing policy once the report is quiet; keep "unsafe-inline" out of script-src.
In a report the technical detail reads: Response headers contained neither content-security-policy nor content-security-policy-report-only.
2. Content-Security-Policy still allows inline or wildcard scripts
Why it matters. A script-src with 'unsafe-inline', 'unsafe-eval' or a * source still lets an injected script run, so the policy gives little of the protection you set it up for.
- Move inline scripts into files and allow them by nonce or hash instead of 'unsafe-inline'.
- Replace * with the exact origins your scripts load from; drop 'unsafe-eval' once no library needs it.
Questions people ask
What does a Content-Security-Policy header look like?
It is one header with directives separated by semicolons, for example Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-r4nd0m'; object-src 'none'; base-uri 'none'; frame-ancestors 'self'. default-src is the fallback for content types you do not list, and each directive names the allowed sources. Build your policy from what your pages actually load.
What is Content-Security-Policy-Report-Only?
It is a header with the same syntax as CSP that blocks nothing and only reports what would have been blocked, to the browser console and to the address in its report-to or report-uri directive. Use it for a few weeks to find every script, style and frame your site needs, adjust the policy, then switch to the enforcing Content-Security-Policy header.
What does 'unsafe-inline' mean in a CSP?
It allows inline <script> blocks, event attributes such as onclick and javascript: links to run. Because injected scripts are usually inline, allowing them removes most of CSP's protection against cross-site scripting. Instead, give legitimate inline scripts a nonce that changes on every response, or a hash of their contents, and move event handlers into script files.
What is frame-ancestors in CSP?
It is the directive that decides which sites may show your page in a frame or iframe. frame-ancestors 'self' allows only your own site and 'none' allows no one, which protects against clickjacking. It replaces the older X-Frame-Options header, and it works only when sent as an HTTP header, not in a meta tag.