Skip to main content
Picking a domain
Language

CSP Builder

Turn the hosts cside observes on your site into a Content-Security-Policy header you can deploy, under Protection > CSP Builder.

CSP Builder turns the hosts cside observes on your site into a Content-Security-Policy header you can deploy. It lives under Protection > CSP Builder in the sidebar, next to CSP Violations.

Writing a Content Security Policy by hand means knowing every host your pages load from, including the ones your vendors load on your behalf. cside already watches those loads, so the builder starts from what actually happened on your site instead of a blank file.

Rolling out gradually

CSP Builder is rolling out gradually. If you don’t see it in your sidebar yet, contact support@cside.dev to enable it for your team.

cside does not serve your policy

The builder generates the header. It never sends it for you and never blocks anything on your site. You copy the header into your own server, CDN, or framework config, and your server is what enforces it.

Picking a domain

Opening CSP Builder from the team level lists your domains with a Script data column. Domains marked Needs setup have no script data yet, and they are still selectable: that page shows you how to install the monitoring script. Select any row to open the builder for that domain.

Inside the builder, the domain dropdown at the top switches between domains without leaving the page.

The suggested policy

The block at the top of the page is the answer you came for: the full header, rebuilt live as you make changes. It carries two lines, and you need both:

  • Content-Security-Policy (or Content-Security-Policy-Report-Only), your policy
  • Reporting-Endpoints, which is what makes violations reach your dashboard

Copy them with the button beside the block. Copying only the first line gives you a working policy that reports nothing back to cside.

The reporting address is built for the specific domain you are on, and it differs depending on whether cside proxies that domain. Always copy it from the page rather than assembling it yourself, or the reports are discarded rather than misfiled.

Long policies are clamped to the first few lines under a fade. Select Show to read the whole thing. Copying and switching modes both work while it is clamped.

Report-only first, then enforce

The Report-only and Enforce toggle above the block picks which header name you copy. The policy body is identical in both.

Deploy the report-only header first. Browsers will report what the policy would have blocked without blocking anything, and those reports land in CSP Violations so you can see what you missed. Once that view is clean, come back, switch to Enforce, and deploy the enforcing header.

The “Before you enforce” check

Copying the enforcing header opens a Before you enforce dialog. It reminds you that enforcing blocks every request the policy does not list and asks you to check three things first:

  1. Inline scripts and styles. No host list allows them. If your pages use <script> blocks, onclick handlers, or style attributes, switch on the inline options for those directives.
  2. data: and blob: URLs. Common for icons, fonts, and inline images. Add them to img-src, font-src, or media-src if you use them.
  3. Your checkout and login flows. The policy covers the pages visitors loaded in the last 30 days. Walk through your payment and sign-in steps first so the vendors they load are in the list.

Select Copy enforcing header to continue, or Cancel to go back.

The default-src switch

Above the directive tabs, a policy-wide default-src ‘self’ switch adds a default-src 'self' floor to the header. It restricts every request type the policy does not list to your own origin, instead of leaving those types unrestricted. It is off until you turn it on, and cside recommends turning it on.

The floor only governs the fetch directives the policy leaves out. It never reaches frame-ancestors, form-action, base-uri, sandbox, or the reporting directives, so you still need to set those yourself.

Reviewing directives

cside fills seven directives from what it observes: script-src, connect-src, img-src, style-src, frame-src, font-src, and media-src. Each gets a tab, and you review them one at a time. The tally under the policy always counts the whole header, not just the tab you are on.

Each tab carries a mark:

MarkWhat it means
A dotNot reviewed yet. Nobody has looked at this directive’s hosts. It is rebuilt from current traffic every time you open it, with every host defaulted by its classification, and nothing you switch off is kept until you save
A checkReviewed and saved. Your decision on every host you saw is kept. Hosts observed later come back proposed on, see below
Greyed out, “no data”cside has seen no traffic of this kind on this domain, so there is nothing to review

Reviewing a directive records your decisions. That is the point of working through the tabs: until someone saves a directive, no one has confirmed that its hosts belong in your policy, and the switches you flip are lost when you leave. Opening a tab and saving is enough. You do not have to change anything. The warning under the host list counts the directives still unreviewed, because enforcing a policy nobody reviewed blocks whatever those directives missed.

Select Save when you are done with a tab. Saving keeps you where you are and keeps your filter.

Hosts that appear after you save

Saving does not freeze a directive to the hosts you saw. It records your answer for those hosts only. A host first observed after the save was never a decision you made, so the builder treats it the same way in a reviewed and an unreviewed directive: it comes back switched on, defaulted by its classification (on for everything except Blocked by you and Flagged malicious), and it is included in the header shown at the top of the page. The next time you copy that header, the new host is in it, whether or not anyone saves again.

That is a proposal, not a change to your live policy: nothing reaches your site until you deploy the copied header. Defaulting new hosts on means a vendor that started working after your save is not silently dropped from your next copy. When you return to the builder, check the hosts you do not recognize, switch them off, and save again so the decision is kept.

Save limits

A directive can hold up to 5,000 sources, and the whole saved policy up to 512 KB of sources. Saving past either cap fails with an error naming the limit. If you hit them, use wildcard families (below) instead of listing every subdomain, or turn off hosts you do not need.

Host groups

Within a directive, hosts are grouped by how cside classifies them, and each group has a bulk switch in its header except where noted.

GroupWhat it meansOn by default
First partyYour own domainYes
Known vendorsA vendor cside recognizes as a large, reputable brandYes
Approved by youA hostname your team approved in Resources InventoryYes
UnvettedEverything cside could not attribute. This is the group the review exists forYes
Blocked by youYour team blocked this hostNo
Flagged maliciouscside blocked this host across all customersNo

Unvetted, Blocked by you, and Flagged malicious have no bulk switch. Most hosts on most domains land in Unvetted, so a single switch would rewrite nearly your whole policy without anyone looking at it, and turning a blocked or malicious host back on should be a decision you take one host at a time with the warning in front of you.

Collapsing a group only hides its rows. The hosts keep whatever you left them on, still count in the tally, and still go into the saved policy. Searching expands every group, so a host you search for is never hidden behind a collapsed header.

Alert counts shown next to a host are informational. An alert never changes whether a host is switched on.

*.csidetm.com and *.csidefd.com are always in the policy and cannot be switched off. A policy that blocked cside’s own script would stop the monitoring the policy was built from.

Wildcard vendor families

When a vendor serves from many subdomains, such as a.vendor.com, b.vendor.com, and cdn.vendor.com, the builder collapses them into a single *.vendor.com row. The family row has one switch and counts as one entry in the policy. Expand the row to see the addresses it covers.

If you turn the wildcard off, you can pick the exact addresses you need one at a time, and each one then counts as its own entry. A family whose addresses are already covered by a wider wildcard you have on has no switch of its own; turn that wider wildcard off to manage the addresses separately.

A Mixed family has only some addresses allowed individually. New addresses in that family default to off. A Covered family inherits a wider approved wildcard and has no separate switch. If cside blocks an address inside an allowed wildcard family, the row warns you: the wildcard still allows that address in the generated CSP.

Policy options

Above the host list, Policy options toggles the source keywords a directive can carry. Which ones appear depends on the directive you are editing:

KeywordWhat it does
'self'Allows resources served from your own origin. On by default, and available on every directive
'unsafe-inline'Allows inline blocks. Offered on script-src and style-src, off by default on both. On style-src it allows style attributes and <style> blocks; on script-src it allows <script> blocks and onclick-style handlers. Each switch names the consequence: on script-src, any inline script on your pages will run, including one injected into the page
'report-sample'Includes a snippet of the blocked code in each violation report. Offered on script-src and style-src, where it helps identify what was blocked

Adding a host cside hasn’t seen

Select Add a host in the toolbar above the list to add a hostname by hand. Use it for a host you know your site needs but that has not appeared in traffic yet, such as a vendor you are about to launch or something that only loads on a page cside does not monitor.

Entries are validated against the directive you are editing. Hostnames are accepted anywhere, with a leading *. wildcard if you need one. data: and blob: are accepted only under img-src, font-src, and media-src. Ports, paths, schemes, and quoted keywords are rejected.

If you already send a CSP

When cside has observed a Content-Security-Policy header on the domain, a banner appears above the policy showing the one seen most often over the last 30 days.

Merge our policy into yours rather than replacing your header. The builder only fills directives it can back with observed traffic, so a policy generated here has nothing to say about frame-ancestors, form-action, base-uri, or object-src. Swapping your whole header for this one drops every directive you were already enforcing that we make no suggestion for.

The policy shown in the banner is what cside observed, not your server config. Nonces and query strings are normalized to wildcards, and it can differ from any single page’s real header, so compare it against your configuration rather than copying it.

Before you deploy

  • Deploy the report-only header first and watch CSP Violations before you enforce
  • Work through every directive tab. The warning under the host list tells you how many are still unreviewed, and reminds you that enforcing would block whatever they missed
  • Come back after you deploy. Hosts observed after your save come back switched on and enter the next header you copy, so review them and save again
  • Copy both lines, the policy and Reporting-Endpoints
  • Merge into your existing header rather than replacing it
  • Adjusting your CSP: CSP violation reporting, retention limits, and exporting reports
  • Adding cside to your CSP: what to change in a policy you already maintain so the cside script keeps working
  • Resources Inventory: review and approve hostnames. Approved hostnames arrive here in the Approved by you group
Was this page helpful?