CSP Checker: How to Test Your Content-Security-Policy in Production
A CSP checker confirms your policy is set, parsed, and enforced correctly in production. Five techniques you can run today, plus a CI pattern.
Checking the header is not the same as checking the behaviour.
- Confirm the header arrives intact with curl and DevTools.
- See real violations through report-only mode.
- Add a Playwright regression test to catch policy drift in CI.
- Use CSPify to surface violations across apps and environments.
A content security policy checker is an essential tool for any security or platform engineering team. Setting a CSP header in your application code or reverse proxy is only the first step. The gap between “the header is set” and “the policy actually works in production without breaking the site” is vast. A proper CSP tester validates that your directives are syntactically correct, securely configured, and actively enforced by the browser.
Whether you are using a CSP generator to Build a CSP from scratch or refining an existing one, you need a reliable way to verify its behaviour. In this guide, we will explore what it means to check a CSP, five concrete ways to test your header, how to safely deploy changes, and how to build automated regression tests in your CI/CD pipeline.
What “checking” a CSP actually means
When engineers talk about a CSP checker, they often mean different things depending on their role and the stage of the deployment pipeline. Checking a Content Security Policy is not a single action; it is a multi-layered verification process.
Header check vs. directive check vs. behaviour check
To thoroughly test your CSP, you must evaluate it across three distinct dimensions:
- The Header Check (Delivery): Does the HTTP response actually contain the
Content-Security-PolicyorContent-Security-Policy-Report-Onlyheader? Is it formatted correctly? Are there multiple conflicting headers being sent by different layers of your infrastructure (e.g., your application framework and your CDN)? - The Directive Check (Syntax and Security): Are the directives inside the header valid? Are you using deprecated features? Does the policy actually provide security value, or is it weakened by overly permissive sources like
unsafe-inlineor wildcard (*) domains? - The Behaviour Check (Enforcement): How does the browser interpret the policy when rendering your specific web application? Does it block malicious scripts as intended? More importantly, does it accidentally block legitimate third-party scripts, fonts, or API calls that your site relies on?
A comprehensive CSP tester strategy incorporates all three checks. You use static analysis to verify the syntax and security posture, network tools to verify delivery, and runtime monitoring to verify behaviour in the real world.
Five ways to check a CSP header
There is no single “best” way to test a CSP. The right approach depends on whether you are developing locally, reviewing a pull request, or monitoring a live production environment. Here are five concrete techniques you can use today.
1. curl -I for the raw header
The fastest way to verify that your web server or CDN is delivering the CSP header is to use curl. By fetching only the HTTP headers (-I or --head), you can inspect the raw response before the browser even parses it.
curl -I https://example.com | grep -i content-security-policy
This simple command is incredibly powerful. It immediately tells you if the header is present, if it is in enforcement mode or report-only mode, and if multiple headers are being concatenated. If you are debugging why a policy is not working, always start here. If curl doesn’t see the header, the browser won’t either.
2. Browser DevTools network panel
While curl is great for the terminal, you often need to check the header in the context of a full page load. The Network panel in your browser’s Developer Tools is the perfect CSP checker for this.
- Open Chrome DevTools (or Firefox/Safari equivalents).
- Navigate to the Network tab.
- Reload the page.
- Click on the primary document request (usually the first item in the list).
- Inspect the Response Headers section.
Here, you can see the exact Content-Security-Policy header that the browser received. This is particularly useful for verifying that intermediate proxies or edge workers haven’t stripped or modified the header before it reached the client.
3. Browser DevTools console (violations)
To understand how your policy behaves, you need to look at what it blocks. The browser Console is your immediate feedback loop for CSP violations.
When a resource violates your policy, the browser logs an error in the Console. For example:
Refused to load the script 'https://example-tracker.com/analytics.js' because it violates the following Content Security Policy directive: "script-src 'self'".
This is the most direct form of a CSP test. It tells you exactly which directive failed and which URL was blocked. For more detailed information, refer to the Chrome DevTools “Inspect CSP violations” docs.
4. Static analysis with a CSP evaluator
Checking the syntax and security strength of your policy manually is error-prone. A CSP evaluator automates this process. Evaluators parse your policy string and flag common misconfigurations, deprecated directives, and security bypasses.
For example, an evaluator will warn you if you use unsafe-inline without a nonce or hash, or if your object-src is missing, which could allow Flash or Java applets to execute. Tools like Google’s CSP Evaluator or the CSPify policy analyzer provide instant, static feedback on your header’s robustness.
5. Runtime monitoring with report-uri/report-to
The most advanced and reliable way to check a CSP is to let your users’ browsers do it for you. By configuring the report-uri or report-to directives, you instruct the browser to send a JSON payload to a specified endpoint whenever a violation occurs.
Here is an example of the JSON payload sent by the report-to mechanism:
{
"csp-report": {
"document-uri": "https://example.com/checkout",
"referrer": "https://example.com/cart",
"violated-directive": "script-src-elem",
"effective-directive": "script-src-elem",
"original-policy": "default-src 'self'; script-src 'self' https://trusted.com; report-uri https://api.cspify.io/report",
"disposition": "enforce",
"blocked-uri": "https://malicious-domain.com/keylogger.js",
"line-number": 12,
"column-number": 34,
"source-file": "https://example.com/checkout",
"status-code": 200,
"script-sample": ""
}
}
This runtime data is invaluable. It provides a continuous, real-world CSP test across all browsers, devices, and user sessions. For a deep dive into the reporting mechanism, review the W3C report-to directive reference or the MDN Content-Security-Policy reference.
Testing CSP changes before they reach production
Deploying a new or modified CSP directly to production is a recipe for disaster. A single typo can break critical functionality, such as payment gateways or analytics. You must test your policy in safe environments first.
Local Docker container with the new header
The earliest stage of testing should happen on the developer’s machine. If you run your application in a local Docker container, configure your local web server (e.g., Nginx, Apache, or your Node.js framework) to inject the new CSP header.
This allows developers to catch obvious breakages immediately. If a new third-party widget is added, the developer will see the CSP violation in their local DevTools and can update the policy before committing the code.
Staging deploy with Content-Security-Policy-Report-Only
When moving to a staging or pre-production environment, always use report-only mode. In this mode, the browser evaluates the policy and sends violation reports, but it does not block any resources.
Here is an example of a header you might test in staging:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://js.stripe.com; style-src 'self' 'unsafe-inline'; report-uri https://api.cspify.io/report
By deploying this header to staging, your QA team and automated tests can interact with the application normally. Meanwhile, your CSP monitoring tool collects violation reports, allowing you to identify and fix missing sources before enforcing the policy.
A/B testing the header on a fraction of traffic
For high-traffic applications, even staging environments might not capture all edge cases. A sophisticated approach is to A/B test the enforced CSP on a small percentage of production traffic (e.g., 1% or 5%).
Using your CDN or edge compute platform (like Cloudflare Workers or AWS Lambda@Edge), you can conditionally inject the enforced header for a subset of users while keeping the rest on report-only mode. Monitor your error rates, conversion metrics, and CSP violation reports closely. If everything looks stable, gradually roll out the enforced policy to 100% of traffic.
Common CSP failures the checker catches
A robust CSP tester will quickly reveal the hidden dependencies of your modern web application. Here are the most common failures you will encounter when testing a new policy. If you are looking for secure configurations to resolve these, review our CSP header examples.
GA4 / GTM blocked by script-src
Google Analytics 4 and Google Tag Manager require complex configurations. They not only load scripts from https://www.googletagmanager.com, but they also often inject inline scripts and load additional resources dynamically. If your script-src is too strict, your analytics will silently fail, leading to massive data loss. A CSP checker will flag these blocked scripts immediately.
Stripe.js iframe blocked by frame-src
Payment processors like Stripe use iframes to securely collect credit card information, isolating the sensitive data from your application’s DOM. If you forget to include https://js.stripe.com in your frame-src (or child-src) directive, the payment form will not render, directly impacting your revenue. Testing your checkout flow with a CSP validator is critical.
Hotjar / Sentry blocked by connect-src
Tools like Hotjar (for session recording) and Sentry (for error tracking) need to send data back to their respective servers via XHR or Fetch requests. If their endpoints are not whitelisted in your connect-src directive, the browser will block the outgoing requests. The scripts will load, but they will be unable to transmit their payloads.
Web fonts blocked by font-src
Custom web fonts from Google Fonts or Adobe Fonts are ubiquitous. However, they are often loaded via stylesheets that then request the actual font files (.woff2, etc.). If your font-src does not allow the specific font delivery domains (e.g., https://fonts.gstatic.com), your site will fall back to system fonts, ruining your carefully crafted design.
Inline styles from a CMS blocked by style-src
Content Management Systems (CMS) and rich text editors frequently inject inline style attributes directly into HTML elements. If your style-src does not include 'unsafe-inline', the browser will strip these styles, resulting in broken layouts and unstyled content. A CSP tester will highlight every instance where inline styles are blocked, forcing you to decide whether to refactor the code or loosen the policy.
Building a CSP regression test in CI
Manual testing is insufficient for long-term maintenance. As your application evolves, your CSP must evolve with it. To prevent regressions, you should integrate CSP checking into your Continuous Integration (CI) pipeline.
Playwright assertion on the response header
End-to-end testing frameworks like Playwright or Cypress can intercept network requests and assert on the HTTP response headers. This ensures that your application is always serving the expected CSP.
Here is an example of a Playwright assertion checking the directive list:
import { test, expect } from '@playwright/test';
test('CSP header is present and correctly configured', async ({ page }) => {
const response = await page.goto('https://staging.example.com');
// Ensure the response is valid
expect(response).not.toBeNull();
// Retrieve the CSP header
const cspHeader = response!.headers()['content-security-policy'];
// Assert the header exists
expect(cspHeader).toBeDefined();
// Assert specific directives are present
expect(cspHeader).toContain("default-src 'self'");
expect(cspHeader).toContain("script-src 'self' https://trusted.cdn.com");
expect(cspHeader).toContain("frame-ancestors 'none'");
// Assert dangerous directives are NOT present
expect(cspHeader).not.toContain("'unsafe-inline'");
});
Snapshot of expected directives
For more complex policies, you can use snapshot testing. Extract the CSP header, parse it into a structured object, and compare it against a known-good snapshot stored in your repository. If a developer accidentally removes a critical directive or adds an overly permissive source, the snapshot test will fail, blocking the pull request.
Failing the build when the policy weakens
The ultimate goal of a CI-based CSP checker is to fail the build if the security posture degrades. By combining header assertions, snapshot testing, and static analysis tools (run via CLI in your pipeline), you can guarantee that no deployment ever weakens your Content Security Policy.
Tooling comparison: curl, DevTools, csper.io tester, CSPify
Choosing the right CSP tester depends on your specific needs. Here is a comparison of popular tooling options:
| Feature | curl | Browser DevTools | Static Evaluators | CSPify |
|---|---|---|---|---|
| Price | Free | Free | Free | Free / Paid |
| Runtime Data | No | Local only | No | Yes (Global) |
| Multi-environment | Manual | Manual | No | Yes |
| CI Integration | Yes (via scripts) | No | Yes (CLI tools) | Yes (API) |
| Alerting | No | No | No | Yes (Slack, Email) |
| Data Retention | None | Session only | None | Up to 90 days |
While curl and DevTools are essential for local debugging, they cannot provide visibility into what your users are experiencing. Static evaluators are great for point-in-time checks, but they don’t catch runtime breakages. For comprehensive, continuous monitoring across multiple environments, a dedicated platform like CSPify is required.
Frequently asked questions
How do I test a CSP without breaking my site?
The safest way to test a CSP is to use the Content-Security-Policy-Report-Only header. This instructs the browser to evaluate the policy and report violations to a specified endpoint without actually blocking any resources. This allows you to observe the impact of the policy in production safely.
What is the best free CSP checker?
For local debugging, your browser’s DevTools (Network and Console panels) are the best free tools available. For static analysis, Google’s CSP Evaluator is a highly regarded free tool. For basic runtime monitoring, CSPify offers a robust free tier.
Can I check a CSP with curl?
Yes. You can use the command curl -I https://yourdomain.com to fetch the HTTP response headers and verify that the Content-Security-Policy header is present and correctly formatted.
How do I see CSP violations in Chrome DevTools?
Open Chrome DevTools, navigate to the Console tab, and look for error messages highlighted in red. CSP violations typically begin with “Refused to load…” or “Refused to execute…” and specify the violated directive and the blocked resource URL.
Does CSP report-only mode count as testing?
Absolutely. Deploying a policy in report-only mode is the most critical phase of CSP testing. It provides real-world data on how the policy behaves across different browsers, devices, and user flows, allowing you to identify and fix issues before enforcing the policy.
How do I test a CSP in CI/CD?
You can integrate CSP testing into your CI/CD pipeline by writing end-to-end tests (using tools like Playwright or Cypress) that assert the presence and content of the CSP header. You can also run static analysis CLI tools to check the policy’s security posture during the build process.
What’s the difference between a CSP checker and a CSP evaluator?
A CSP evaluator typically performs static analysis on a policy string to identify syntax errors, deprecated directives, and security weaknesses. A CSP checker is a broader term that encompasses evaluators, network inspection tools (like curl), and runtime monitoring systems that verify the policy’s actual behaviour in the browser.
Can I check a CSP behind authentication?
Yes. If you are using browser DevTools or automated testing frameworks like Playwright, you can log in to your application and navigate through authenticated routes to trigger and observe CSP violations. Runtime monitoring via report-uri also works seamlessly behind authentication, as the browser automatically sends reports for any violations it encounters.
Catch CSP regressions before customers do
A robust Content Security Policy is a living document. As your application grows, new scripts are added, third-party services change their delivery networks, and new vulnerabilities emerge. Checking your CSP once during initial implementation is not enough. You need continuous visibility to ensure your policy remains effective and your site remains functional.
While curl, DevTools, and static evaluators are excellent for local debugging and point-in-time checks, they cannot protect you from regressions in production. To truly operationalize your CSP, you need automated alerting, long-term data retention, and multi-environment coverage.
Try CSPify Growth to add alerting, retention, and multi-app coverage to your CSP testing workflow. If you are just starting out, you can also Start free to begin collecting violation reports today. Don’t wait for a broken checkout flow to tell you your CSP is misconfigured.
Catch CSP regressions before customers do
Start Growth to add alerting, retention, and multi-app coverage to your CSP testing workflow.