Website Health Guides

Content-Security-Policy (CSP): Setup and Common Mistakes

Learn what Content-Security-Policy does, how to set up CSP safely, common CSP directives, report-only testing and mistakes that can break websites.

By CheckDomainHealth Editorial Team Reviewed by Dionis Ceban Updated Jun 28, 2026 8 min read Beginner

Introduction

Content-Security-Policy, or CSP, is an HTTP security header that tells browsers which resources are allowed to load on a website. It can control scripts, styles, images, fonts, frames, connections, media and other resource types.

A good CSP can reduce the impact of cross-site scripting, unwanted script injection and untrusted third-party resources. But CSP must be configured carefully. A policy that is too strict can break analytics, fonts, payment widgets, maps, videos, page builders, forms or other legitimate website features.

Quick answer

Quick answer

CSP controls which sources a browser may load resources from. Start with Content-Security-Policy-Report-Only, review blocked resources, allow only trusted sources, then move gradually to enforcement. Avoid broad wildcards and test scripts, styles, fonts, images, frames, forms and third-party tools before going live.

Content-Security-Policy

Content-Security-Policy is a browser security policy delivered through an HTTP response header.

It can restrict:

  • JavaScript sources
  • CSS/style sources
  • image sources
  • font sources
  • iframe/frame sources
  • API/connect sources
  • form submission targets
  • media sources
  • object/embed sources
  • base URL behavior
  • who can embed your site

CSP does not remove vulnerabilities from code, but it can reduce what injected or unwanted code is allowed to do in the browser.

What CSP protects

CSP can help reduce risk from browser-side attacks and unsafe resource loading.

  • cross-site scripting impact
  • injected malicious scripts
  • unauthorized third-party JavaScript
  • clickjacking when using frame-ancestors
  • mixed content loading
  • unsafe plugin/object embeds
  • data exfiltration through unexpected connections
  • loading assets from untrusted domains

CSP is a defense-in-depth control. It should be used together with secure coding, input validation, updates and server hardening.

Important directives

default-src

Fallback rule for resource types that are not defined separately.

script-src

Controls where JavaScript can load from.

style-src

Controls CSS and style sources.

img-src

Controls image sources.

font-src

Controls font sources.

connect-src

Controls fetch, XHR, WebSocket and API connections.

frame-src

Controls what can be loaded inside frames.

frame-ancestors

Controls who can embed your site in an iframe.

form-action

Controls where forms can submit.

object-src

Controls legacy object/embed/plugin content.

base-uri

Restricts the base URL used by the document.

upgrade-insecure-requests

Asks browsers to upgrade HTTP resource requests to HTTPS.

Report-only mode

The safest way to introduce CSP is to start in report-only mode.

Report-only header
Content-Security-Policy-Report-Only

Report-only mode lets you see what the policy would block without actually breaking the website.

Use report-only to:

  • discover required script sources
  • discover required style sources
  • identify third-party tools
  • catch blocked fonts/images
  • find broken embeds
  • detect unexpected resources
  • test policy changes safely

Do not start with a strict enforced CSP on a complex production website unless you already know every required resource.

Basic example

Basic CSP example
Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  style-src 'self';
  img-src 'self' https:;
  font-src 'self' https:;
  object-src 'none';
  base-uri 'self';
  frame-ancestors 'self';
  form-action 'self';

This example allows resources mostly from the same site and HTTPS image/font sources, blocks legacy object embeds and prevents the site from being framed by unrelated domains.

This is only an illustrative starting point. It may break analytics, external fonts, embedded videos, payment widgets, maps or chat tools until those trusted sources are added.

CSP keywords

'self'

Allows resources from the same origin.

'none'

Allows nothing for that directive.

'unsafe-inline'

Allows inline scripts or styles. Often weakens CSP.

'unsafe-eval'

Allows eval-like JavaScript execution. Usually avoid when possible.

https:

Allows resources from HTTPS sources.

data:

Allows data URLs. Sometimes needed for images, but should be limited.

nonce

Allows specific inline scripts/styles with a server-generated nonce.

hash

Allows specific inline scripts/styles matching a hash.

Avoid adding unsafe-inline or unsafe-eval unless you understand why the site needs them.

Why this matters

Why this matters

CSP matters because modern websites often load scripts, styles, fonts, images and tools from many places. Without a policy, the browser has fewer rules for deciding which resources are trusted. If an attacker injects script into a page, a strong CSP can reduce what that script can load or execute.

CSP is especially useful for login pages, dashboards, checkout flows, SaaS apps, WordPress sites, admin panels and pages with user-generated content.

How to check CSP

Use HTTP Header Checker to inspect whether your site sends a Content-Security-Policy header.

Check:

  1. Header presence — Look for Content-Security-Policy or Content-Security-Policy-Report-Only.
  2. Final response — Check the final HTTPS page after redirects.
  3. Important pages — Test homepage, login, checkout, dashboard, forms and embedded pages.
  4. Browser console — Look for CSP violation messages.
  5. Third-party tools — Verify analytics, fonts, maps, videos, payments and chat widgets.
  6. Report-only logs — Review violation reports before enforcement.
  7. CDN/origin behavior — Confirm the header is not duplicated or overwritten.

Check your CSP

Use HTTP Header Checker to inspect whether your site sends a Content-Security-Policy header.

Run HTTP Header Check →

Common problems

CSP missing

Medium

The browser receives no resource-loading policy.

Next step: Start with a report-only policy and build from observed resources.

CSP too strict

High

Legitimate scripts, styles, fonts, images or embeds are blocked.

Next step: Review browser console violations and allow only trusted required sources.

unsafe-inline used broadly

Medium

Inline scripts/styles are allowed, reducing CSP protection.

Next step: Use nonces, hashes or refactor inline code where practical.

unsafe-eval required

Medium

Some JavaScript relies on eval-like behavior, weakening protection.

Next step: Identify the dependency and remove or isolate it if possible.

Third-party scripts blocked

Medium

Analytics, chat, payment or tracking scripts do not load.

Next step: Add only the specific trusted domains needed.

Fonts or images missing

Low

font-src or img-src does not include required asset sources.

Next step: Add trusted font/image CDNs or host assets locally.

Forms stop submitting

High

form-action blocks legitimate form targets.

Next step: Allow only trusted form endpoints.

Embeds stop working

Medium

frame-src or frame-ancestors blocks videos, maps or embedded tools.

Next step: Allow specific trusted embed domains.

Duplicate CSP headers

Medium

CDN and origin send conflicting policies.

Next step: Manage CSP in one place or ensure policies are compatible.

Enforced too early

High

A strict policy was deployed before testing.

Next step: Switch to report-only, fix violations, then enforce gradually.

How to set up CSP

  1. Step 1: Inventory resources

    List scripts, styles, fonts, images, APIs, frames and form destinations your site uses.

  2. Step 2: Start with report-only

    Deploy Content-Security-Policy-Report-Only so violations are visible without breaking the site.

  3. Step 3: Review violations

    Use browser console and reports to identify required trusted sources.

  4. Step 4: Allow specific sources

    Prefer exact trusted domains instead of broad wildcards.

  5. Step 5: Avoid unsafe patterns

    Reduce unsafe-inline and unsafe-eval where practical.

  6. Step 6: Test important flows

    Check login, checkout, forms, dashboards, analytics, payment widgets and embeds.

  7. Step 7: Enforce gradually

    Move from report-only to enforcement after testing.

  8. Step 8: Monitor after deployment

    Watch console errors, user reports, analytics drops and CSP reports.

Before enforcement

Confirm these items before switching from report-only to enforced CSP.

Policy tested in report-only mode

Violations reviewed and understood.

Homepage works

Main page loads without CSP blocks.

Login works

Authentication flows are not blocked.

Forms submit

form-action allows trusted endpoints.

Checkout/payment works

Payment widgets and gateways load correctly.

Analytics works

Tracking scripts and beacons are allowed.

Fonts load

font-src and style-src include required sources.

Images load

img-src includes required asset hosts.

Videos/maps/chats work

frame-src and connect-src allow embeds.

No important console violations

Critical resources are not blocked.

CSP is not duplicated

CDN and origin do not send conflicting policies.

CDN/origin rules are consistent

One primary place manages the policy.

Report endpoint is monitored if used

Violation reports are reviewed.

fallback/default-src is defined

Default rule covers unspecified resource types.

object-src is restricted

Legacy embeds and plugins are limited.

frame-ancestors is configured

Clickjacking protection is in place.

CSP examples
Report-only example:

Content-Security-Policy-Report-Only:
  default-src 'self';
  script-src 'self' https://www.googletagmanager.com;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  font-src 'self' https://fonts.gstatic.com;
  img-src 'self' https: data:;
  connect-src 'self' https://www.google-analytics.com;
  object-src 'none';
  base-uri 'self';
  frame-ancestors 'self';

Stricter enforced example:

Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  style-src 'self';
  img-src 'self' https:;
  font-src 'self';
  object-src 'none';
  base-uri 'self';
  frame-ancestors 'self';
  form-action 'self';

These examples are illustrative. Do not copy them blindly. Your required sources depend on your website, plugins, CDN, analytics and third-party integrations.

Server and CDN configuration
Nginx:
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self';" always;

Apache:
Header always set Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self';"

Report-only:
Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; report-uri /csp-report

CSP can be configured in the web server, CDN, application framework or hosting panel. Choose one primary place to avoid conflicts.

Syntax and support vary by server, CDN and framework. Test in staging where possible.

WordPress CSP

WordPress sites often need extra care because themes, plugins and page builders may load external resources.

  • page builders
  • caching plugins
  • security plugins
  • Google Fonts
  • Google Analytics
  • Tag Manager
  • YouTube embeds
  • Google Maps
  • payment widgets
  • contact forms
  • chat widgets
  • CDN-hosted assets
  • inline scripts added by plugins

For WordPress, report-only mode is strongly recommended before enforcement because plugins can change resource loading after updates.

Third-party tools

Third-party tools often require multiple directives.

Analytics scripts

May need script-src, img-src and connect-src.

Video embeds

May need frame-src, img-src and script-src.

Payment tools

May need script-src, frame-src, connect-src and form-action.

Fonts

May need font-src and style-src.

Only allow the domains required by the provider’s documentation. Avoid adding unrelated domains just to silence errors.

Frequently asked questions

What does CSP do?

CSP tells browsers which resources are allowed to load on a page.

Can CSP break my website?

Yes. A strict policy can block legitimate scripts, styles, fonts, images, forms or embeds.

Should I use report-only first?

Yes, especially for complex sites, WordPress sites, e-commerce or sites using many third-party tools.

Is unsafe-inline bad?

It weakens CSP because inline code is allowed. Use nonces, hashes or code changes where practical.

Does CSP replace secure coding?

No. CSP is an extra protection layer, not a replacement for fixing vulnerabilities.

Where should CSP be configured?

Usually at the server, CDN, application or hosting level. Avoid conflicting duplicate policies.

What is a good first CSP?

Start with report-only, restrict object-src and base-uri, define default-src, then refine script/style/image/font/connect/frame rules.

Use these free tools to verify your configuration after applying changes.

Browse all Website Health guides →

Need help applying this fix?

Send us your domain, report link or issue details. CheckDomainHealth will review the request and route it to the right technical team if hands-on support is needed.

Get Help Run Domain Health Check

Was this guide helpful?

Your feedback helps us improve our guides for everyone.