What is a content security policy?
SECURITY_CSP_MISSING template
The issue
A site without a Content Security Policy lets the browser run any script that reaches the page, from any origin. When something unexpected gets in, through an injection bug or a compromised third-party script, nothing stops it and nothing records it. The page looks the same either way.
The cause is a missing header. A CSP is a list the site sends with each response naming which sources may supply scripts, styles, frames and other resources. Without one, the browser’s defaults allow nearly everything.
Scope
The policy is sent per response, so each page carries its own or none. In practice it is set once, in the server, framework or CDN, and every page served the same way gets the same policy.
How to check you have it
- In probeo: a response with no
Content-Security-Policyheader is reported ascsp-missing, graded critical. AContent-Security-Policy-Report-Onlyheader on its own doesn’t count, because it blocks nothing. - By hand: run
curl -sI https://your-site.example/ | grep -i content-security-policy. No output means no policy. - With a tool: paste a policy into Google’s CSP Evaluator to see which directives are missing or too broad.
The fix
Send a Content-Security-Policy header that names the sources the site actually uses.
Start from what the pages load today: the site’s own origin, its CDN, analytics and any embeds. A common starting point is default-src 'self', with script-src, object-src 'none', base-uri 'none', form-action 'self' and frame-ancestors 'none' set explicitly, then widened only where a real dependency needs it. Run it as Content-Security-Policy-Report-Only first to see what it would block.
Done when: every page sends an enforced policy that reflects the site’s real dependencies, and the check above comes back clean.
Do not
- Do not allow every source by default to make the header pass.
- Do not treat the header’s presence as the goal; what it allows is what matters.
- Do not leave a report-only policy in place as the finished state.
What a policy controls
Each directive covers one kind of resource: script-src for scripts, style-src for styles, img-src for images, frame-src for frames the page embeds. default-src is the fallback for fetch directives that aren’t set. A few directives don’t fall back to it at all: base-uri, form-action and frame-ancestors restrict nothing unless they are set.
When a resource breaks the policy, the browser blocks it and logs a violation in the console. With a report-to or report-uri directive, it also sends a report to the endpoint named there.
FAQ
Is a Content Security Policy the same as a security scan?
No. A CSP doesn’t look for problems. It states what the page may load, so the browser can refuse anything outside that.
Can a site work without a CSP?
Yes. Nothing breaks without one. What is missing is any limit on what the browser will run.
Does a CSP replace other security controls?
No. It doesn’t replace output encoding, validation, authentication or access control. It limits what an injection can do when one of those fails.
Why do CSP changes surface unexpected issues?
Because many dependencies were never written down. A policy lists what is allowed, so anything not on the list shows up as a violation.
Should every page use the same CSP?
Usually, when pages share templates and dependencies. Where they differ, the difference should be deliberate.
Is CSP only a security concern?
Mostly, but not only. A policy is also a written record of what the site loads, which is useful when nobody is sure anymore.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.