How to use the CSP Builder
CentralCSP Team ·
Last update:
Writing a Content Security Policy (CSP) by hand is slow and easy to get wrong. You list every script, style, font, and image source the page loads, miss a few, and either break the site or leave a gap. The CSP Builder takes a different route. It reads the violation reports your site is already sending and turns them into a policy that covers what your pages actually load.
This post walks through the Builder end to end: pick a starting policy, choose how much report data to analyze, generate the policy, review each source, and deploy. You get a header you can ship instead of a blank file and a long afternoon.
If CSP is new to you, read get started with Content Security Policy first, then come back here to generate your first real policy.
What the CSP Builder does
The CSP Builder is a tool inside the CentralCSP dashboard, so you run it against your account's report data rather than installing anything.
A Content Security Policy is an HTTP response header that tells the browser which sources a page may load scripts, styles, images, and other resources from. The browser enforces it; anything not allowed is blocked and reported.
The Builder works from those reports. When your site sends violation reports to a reporting endpoint, every blocked or would-be-blocked resource is recorded with its directive and source. The Builder reads that history and assembles a policy that allows the sources your application legitimately uses, with secure defaults applied for the rest. You review the result before anything ships.
It does not enforce or proxy traffic. It produces a header; you deploy that header on your server, and the browser does the enforcing.
Before you start
You need report data for the Builder to learn from. Two things have to be in place:
- A reporting endpoint. Your site sends CSP reports to a CentralCSP endpoint in the form
https://<Endpoint-ID>.report.centralcsp.com. See get started with CSP reporting for the setup. - Some report history. The more traffic the reports cover, the more complete the generated policy. A longer window catches the resources that only load on rarely visited pages, so let reports accumulate across a full traffic cycle before you generate.
Run your first policy in Report-Only mode to gather reports without blocking anything. Report-Only sends the same violation reports as an enforced policy, so the Builder gets real data while your site keeps working.
Step 1. Pick a starting policy
The Builder starts from a base policy and refines it. You can let it detect the policy your site already serves, start from a strict CSP starter template, or paste a custom one.
A common starting point is a strict baseline that denies everything by default and opens up only what the reports prove you need:
Content-Security-Policy-Report-Only:
default-src 'self';
script-src 'self' 'report-sample';
style-src 'self';
img-src 'self';
font-src 'self';
object-src 'none';
base-uri 'none';
form-action 'self';
frame-ancestors 'none';
report-uri https://<Endpoint-ID>.report.centralcsp.comHere default-src sets the fallback, object-src and base-uri lock down legacy attack surface, and frame-ancestors blocks clickjacking. The 'report-sample' keyword tells the browser to include a snippet of the blocked content in each report, which helps you tell legitimate code from injected code.
Step 2. Choose a reporting window
Next, pick the time range of reports the Builder should analyze. A longer window covers more of your site's behavior, including pages and flows that only run occasionally. A shorter window reflects only recent traffic.
The Builder reads the violation reports in that window, groups them by directive, and works out which sources your pages actually requested. This is where it learns that your scripts come from your own origin plus a specific analytics host, your fonts from one CDN, and so on.
Step 3. Generate and review the policy
The Builder assembles a policy from the analyzed reports. It adds the sources your application needs per directive and applies secure defaults to the directives that had no legitimate traffic.
A generated policy for a typical site looks like this, one directive per line:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'strict-dynamic' 'nonce-r4nd0m' https://cdn.example.com;
style-src 'self' https://fonts.googleapis.com;
img-src 'self' data: https://*.example.com;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://api.example.com;
object-src 'none';
base-uri 'none';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
report-uri https://<Endpoint-ID>.report.centralcsp.comA few things to notice in a generated header:
script-srccarries the modern approach: a per-request nonce plus'strict-dynamic', so trusted scripts can load the scripts they need without you listing every host. See how'strict-dynamic'works for the keyword, and CSP nonces in Next.js for wiring nonces in app code.connect-src,font-src, andimg-srclist the real hosts seen in your reports, nothing more.upgrade-insecure-requestspushes any plain-HTTP subresource to HTTPS.
If your reports show inline styles or scripts, the Builder surfaces them so you can decide between a nonce, a hash, or refactoring the inline code out. Avoid reaching for 'unsafe-inline'; why unsafe-inline weakens your CSP explains the cost.
Step 4. Review each source
Generation is not the last word. The Builder walks you through the policy directive by directive so you approve what goes in. This is the step that keeps a stray host out of your script-src.
For each source, check that it belongs. A host you recognize (your CDN, your analytics provider) is a keep. A host you do not recognize is worth investigating before you allow it, since the report may reflect an injected or third-party resource you do not want to permit. Reviewing third-party tags is its own task; CSP for Google Analytics and Tag Manager covers the common ones.
Keep the policy in Report-Only while you review. The browser reports against the new policy without enforcing it, so you can confirm it covers real traffic before it can break anything.
Step 5. Deploy the policy
When the policy looks right, copy the header and set it on your server. The exact syntax depends on your stack, and how to set the CSP header in every framework covers each one; here is nginx as an example:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'strict-dynamic' 'nonce-r4nd0m' https://cdn.example.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' data: https://*.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests; report-uri https://<Endpoint-ID>.report.centralcsp.com" always;Switch from Content-Security-Policy-Report-Only to Content-Security-Policy only when you are confident. The two headers can run side by side: enforce the policy you trust on Content-Security-Policy while you test the next iteration on the Report-Only header.
After enforcing, keep the reporting endpoint live. New code and new third parties will surface as fresh reports, and you re-run the Builder to fold them in.
Validate before and after you ship
Two free tools help you check the policy without deploying it first:
- The CSP evaluator grades a policy and flags weak spots, like an overly broad
script-srcor a missingobject-src. - The CSP scanner reads the live header on a URL so you can confirm what production is actually serving.
Run the policy through the evaluator before you enforce it, and scan the live site after, so you know the deployed header matches what you approved.
From generated policy to ongoing monitoring
A policy is not a one-time job. Sites change, dependencies update, and new third-party scripts appear. The same reports that fed the Builder keep flowing, so you see violations as they happen and re-generate when your stack shifts.
For payment pages, that ongoing visibility is also evidence. Continuous script and header monitoring helps you meet PCI DSS v4 requirements 6.4.3 and 11.6.1, where you have to manage and detect changes to the scripts on payment pages. CentralCSP records that history; a QSA signs off on compliance, not us.
Ready to generate a policy from your own reports? Start free and point your site at a reporting endpoint, then run the Builder against real traffic.