# How To Find Out What a Content Policy Would Block With BetterShield?

Send a report-only Content-Security-Policy with BetterShield, read what it would block, and enforce it only after a week with nothing reported.

Send a report-only Content-Security-Policy with **[BetterShield](/)**, read what it would block, and enforce it only after a week with nothing reported.

## What it does

In **[BetterShield](/)**, a Content-Security-Policy tells the browser where a page may load scripts, styles, images, fonts and frames from. **Script-blocking policy** sends one in report-only mode: "Nothing a visitor loads changes; browsers simply tell this site what a policy would have blocked, so you can see the cost before paying it." It is under **HTTPS and browser security** on **BetterShield › Protection › Hardening**, and it starts off.

- Adds `Content-Security-Policy-Report-Only` to front-end pages only: the sign-in page, the REST API and the dashboard never get it.
- Collects what browsers report, "grouped by what was blocked and where it came from, keeping the origin and never the full address." It keeps at most 50 kinds, and takes at most 20 reports from one connection every five minutes.
- Leaves a header of the same name alone if WordPress or another plugin has already set one.

The policy starts the same on every site and has no fields; sources you allow from the reports (below) are added to it:

| What the page loads | Allowed from |
|---|---|
| Anything not listed below | Your own site |
| Scripts | Your own site, plus inline scripts |
| Styles | Your own site, plus inline styles |
| Images | Your own site, plus `data:` images |
| Fonts | Your own site, plus `data:` fonts |
| Who may show the page in a frame | Your own site |

"Your own site" means the exact scheme and host name, so a CDN host name counts as somewhere else.

<span id="set-it-up" aria-hidden="true"></span>

## Step 1: Open Preview the change

Press **Preview the change** on **Script-blocking policy**. The note beside it says it "starts on the report-only header, so nothing a visitor loads changes."

<figure class="doc-shot">
  <img src="/docs/screenshots/content-security-policy.png" alt="Find out what a content policy would block: saved state and available controls in BetterShield." width="980" height="168" loading="lazy" decoding="async">
  <figcaption>Review the state and choices shown on your own site before applying a change.</figcaption>
</figure>

## Step 2: Find out what a content policy would block

- Turn the switch on. The row reads "Watching. Nothing has been reported yet."
- Leave it on through at least a week of ordinary traffic, and read **What it would have blocked** as reports arrive.

**Monitor first** has no watch mode here: this fix is its own trial. `wp bettershield harden csp_report_only --user=<login>` turns it on from the terminal; enforcing is done on the screen only.

### Reading the list

Each line shows the rule, where the blocked item came from, and "once" or "4 times". The 12 most frequent come first, then "And 3 more kinds, reported less often." Rules are named as the browser reports them, such as `img-src`, `frame-src` or `script-src-elem`. A line with no address reads "somewhere this site could not read".

The lines come from visitors' browsers, "so the addresses are theirs rather than this site's." A browser extension can add a line of its own.

### Allowing a source, or clearing the list

Each line has **Allow**. After **Yes: allow it**, its source is added to the rule it was reported on, so browsers load it from there. Anyone can send your site a report, so allow only a source you recognize. Allowed sources are listed under **Sources you allowed**, each with **Remove** (**Yes: remove it**) to take it back off. Inline script, eval, wildcards and bare schemes cannot be allowed this way, and the policy takes at most 30 sources.

**Clear this list** empties the list, for a cause you have fixed or a report that was never real, and **Put the list back** undoes it. Allowing, removing and clearing each start the week without reports again.

### Start enforcing this policy

It is offered only when the fix has been watching for 7 days since it was last turned on, and the list is empty. Until then the row gives the reason instead, such as "Nothing has been reported in 3 of the 7 days this waits for." or "2 kinds of thing would still be blocked." The list is not cleared by time or by turning the fix off and on: allow what you recognize or clear it (see above). Enforcing also waits for a daily check that visitors' browsers can deliver their reports here ("Waiting for the daily check that visitors’ browsers can deliver their reports here."), and is not offered while the report address refuses them.

When it is offered, press it, read "Enforcing sends the same policy for real, so anything it would block stops loading.", and press **Yes: Start enforcing this policy** (or **Cancel**). The same policy then goes out as `Content-Security-Policy`, and browsers keep reporting what it blocks.

**Go back to watching** returns to report-only at once, and the wait never holds it back. Both buttons need a signed-in browser. **Go back to watching** asks for your password when **Ask for my password before removing a protection** is on (**Settings › General**); starting to enforce never does.

## Recommended settings

We recommend turning it on for a week or two on any site: it costs visitors nothing, and the list shows what your pages pull in from elsewhere. Enforce only if the list is still empty after the wait, most likely on a simple site with no outside fonts, analytics, embeds or avatars.

| Site | What we recommend |
|---|---|
| Blog or brochure site | If comments show avatars, WordPress loads them from Gravatar, which appears as an `img-src` line. Treat the list as information. |
| Store (WooCommerce) | Keep it in report-only. Anything the checkout loads from another domain shows on the list, and enforcing would block it. |

## What it can break, and how to undo

- **In report-only, nothing.** Visitors load everything as before.
- **Enforcing** blocks whatever the policy does not allow, on every front-end page. A quiet week is evidence, not a promise. **Go back to watching** undoes it straight away.
- **Turning it off** stops the header and the reports, and forgets the sources you allowed. Turning it on again starts in report-only and restarts the 7 days, even if it was enforcing.
- **Safe mode** pauses the header and the reports. The policy comes back in the mode it was in.

<span id="check-it-is-working" aria-hidden="true"></span>

## Final Outcome

**The row.** The summary counts what was reported, as in "3 kinds of thing would have been blocked.", and after a visitor loads a page it reads "Confirmed on a page a visitor received", with the time.

- **The activity log.** "Hardening applied", "Hardening undone", "Content policy is now enforced" (High), "Content policy is back to watching", "Content policy widened for a source", "Content policy no longer allows a source", "Content policy reports cleared" and "Cleared content policy reports put back".
- **Findings.** No finding opens while it is off. While it is on, **Some protections that are switched on are not working** (Medium) names it if a visitor's page was seen without the header.
- **In the browser.** On a front-end page, signed out, the developer tools show `Content-Security-Policy-Report-Only` in the response headers, and the console lists what it would have blocked.

<figure class="doc-shot">
  <img src="/docs/screenshots/content-security-policy.png" alt="Find out what a content policy would block: saved state and available controls in BetterShield." width="980" height="168" loading="lazy" decoding="async">
  <figcaption>Example Content security policy view. Check the saved values and status on your own site.</figcaption>
</figure>

## Good to know

- Because it allows inline scripts, this policy limits where pages load things from. It does not stop a script written into the page itself.
- The list is kept while the fix is off, and lines are not removed by time or by turning the fix off and on. Enforcing needs it empty: allow the sources you recognize, fix the rest where they come from, then clear the list.

## Related

- [Hardening](/docs/hardening/)
- [HSTS](/docs/hsts/)
- [Security response headers](/docs/security-headers/)
- [Content Security Policy in WordPress](/blog/content-security-policy-wordpress/)
- [WordPress security headers, explained](/blog/wordpress-security-headers/)

This is how you can find out what a content policy would block with BetterShield.

Getting Stuck? Feel free to contact our [Dedicated Support Team](/support/).
