Loading
GGX_LABS
KNOWLEDGE MODULE

Content-Security-Policy Explained

How CSP restricts what a browser is allowed to load, and why it's one of the most effective defenses against XSS.

Core Concept

Content-Security-Policy is an HTTP response header that tells the browser exactly which sources of content — scripts, styles, images, fonts — are allowed to load on a page.

It acts as a second line of defense against cross-site scripting, since even if malicious script gets injected into a page, CSP can prevent it from executing or exfiltrating data.

Insight: CSP doesn't prevent injection itself — it limits what an injected script is actually allowed to do once it's on the page.

Core CSP Directives

A CSP policy is built from a set of directives, each controlling a different resource type.

  • script-src — controls allowed JavaScript sources
  • style-src — controls allowed CSS sources
  • img-src — controls allowed image sources
  • connect-src — controls allowed fetch/XHR/WebSocket targets

Default-src Fallback

The default-src directive acts as a fallback for any resource type not explicitly specified, making it a useful baseline restriction.

Common Implementation Pitfalls

CSP is powerful but notoriously easy to misconfigure in ways that either break functionality or weaken protection.

  • unsafe-inline permitted out of convenience, defeating much of CSP's XSS protection
  • Overly broad wildcards like script-src *
  • Forgetting third-party analytics or ad scripts, breaking functionality
Limitation: A CSP that includes unsafe-inline for scripts provides significantly weaker XSS protection than one using nonces or hashes instead.

Nonces and Hashes for Inline Scripts

Modern CSP implementations avoid unsafe-inline by using cryptographic nonces or content hashes to allowlist specific inline scripts.

A nonce is a random value generated per page load and included both in the CSP header and the script tag — only scripts with a matching nonce are permitted to run.

Per-Request Nonces

Because nonces must be unique per page load, they can't be guessed or reused by an attacker injecting their own script tag.

Report-Only Mode for Safe Rollout

CSP supports a report-only mode that logs violations without actually blocking content, making it safer to roll out incrementally.

  • Content-Security-Policy-Report-Only header for testing
  • report-uri or report-to directives to collect violation data
  • Gradual tightening once violation reports are clean
Insight: Deploying CSP in report-only mode first is the standard way to discover legitimate resource usage before enforcing a policy that might break the site.

Real-World Implementation

CSP deployment is now a standard security hardening step across serious web applications.

  • Financial and authentication pages enforcing strict CSP
  • Report-only rollouts on complex legacy applications
  • Automated CSP violation monitoring integrated into alerting

A well-tuned CSP meaningfully reduces the impact of an XSS vulnerability even when the underlying injection flaw hasn't been fully fixed yet.

Common Mistakes to Avoid

A few common mistakes weaken CSP's effectiveness even when it's technically deployed.

  • Including unsafe-inline for convenience, defeating much of CSP's XSS protection.
  • Using overly broad wildcards like script-src * instead of specific allowlisted origins.
  • Forgetting third-party analytics or ad scripts, breaking functionality after deployment.
  • Skipping report-only mode and enforcing a strict policy without prior testing.
  • Failing to update the policy as new third-party integrations are added over time.
  • Overlooking the frame-src directive when only configuring script and style sources.
  • Assuming a report-only policy provides real protection while testing.
  • Failing to update CSP when adding a new third-party integration to the site.
  • Overlooking the strict-dynamic keyword, which simplifies CSP for modern script loading patterns.
  • Assuming CSP reporting endpoints require no rate limiting of their own.
  • Failing to review third-party CSP violation reports for signs of browser extension interference.
  • Overlooking that some browser extensions inject content that can trigger CSP violations unrelated to the site.

Best Practices Checklist

These practices lead to a genuinely effective, well-maintained CSP.

  • Deploy in report-only mode first to discover legitimate resource usage before enforcing.
  • Use nonces or hashes for inline scripts instead of unsafe-inline.
  • Allowlist specific trusted origins rather than relying on broad wildcards.
  • Monitor CSP violation reports continuously, not just during initial rollout.
  • Update the policy deliberately whenever a new third-party integration is added.
  • Configure frame-src explicitly alongside script and style directives for complete coverage.
  • Treat report-only mode strictly as a testing phase, not a substitute for enforcement.
  • Update CSP configuration as part of the standard checklist for adding new integrations.
  • Consider strict-dynamic for simplifying CSP configuration with modern script loading patterns.
  • Apply rate limiting to CSP reporting endpoints to avoid being overwhelmed by report volume.
  • Review violation reports for patterns suggesting browser extension interference rather than real issues.
  • Filter known extension-related noise when reviewing CSP violation reports for genuine issues.

Frequently Asked Questions

Frequently asked questions about Content-Security-Policy.

Does CSP prevent XSS vulnerabilities from existing?

No — it limits what an injected script is allowed to do once it's on the page, acting as a second line of defense rather than a fix for the underlying flaw.

Why is unsafe-inline considered risky in a CSP?

It significantly weakens XSS protection by allowing any inline script to execute, defeating much of what CSP is designed to prevent.

What's the safer alternative to unsafe-inline for scripts?

Using per-page nonces or content hashes allowlists specific inline scripts without opening the door to all inline script execution.

How should a CSP be rolled out safely?

Starting in report-only mode lets you discover legitimate resource usage and violations before enforcing a policy that might break the site.

What does the default-src directive do?

It acts as a fallback for any resource type not explicitly specified by a more specific directive, providing a useful baseline restriction.

Does CSP cover iframes as well as scripts and styles?

Yes, through the frame-src directive, which is easy to overlook if a policy only addresses script and style sources.

Does report-only mode actually block anything?

No — it only logs violations, providing zero actual protection until the policy is switched to full enforcement.

Should CSP be revisited when adding a new third-party script?

Yes — any new integration needs to be reflected in the policy, or it risks being silently blocked or breaking the CSP's protective value.

What does strict-dynamic do in a CSP policy?

It simplifies script authorization by trusting scripts loaded by an already-trusted script, reducing the need to allowlist every individual source explicitly.

Can browser extensions trigger false CSP violation reports?

Yes — some extensions inject content that can trigger violations unrelated to the site's own code, worth filtering out during report review.

Can browser extensions cause false CSP violation reports?

Yes — some inject content that triggers violations unrelated to the actual site code, worth filtering out during report review.

Analyze Security Headers

Run a security headers scan to see a domain's current Content-Security-Policy configuration.

Launch Tool →
END OF MODULE