[ GF.dev ] All Tools →

Content Security Policy (CSP) Explained: From Basics to Advanced

Published 2026-03-29 · Last modified 2026-03-29

Content Security Policy (CSP) is the most powerful HTTP security header available to web developers. It tells the browser exactly which sources of content are permitted, effectively neutralizing entire classes of injection attacks including cross-site scripting (XSS), data exfiltration, and malicious resource injection.

This article walks through CSP from first principles to advanced techniques like nonce-based policies and report-only deployment. CSP is a key component of the headers covered in our complete security headers guide.

What Is Content Security Policy?

CSP is delivered via the Content-Security-Policy HTTP response header (or a <meta> tag, though the header is preferred). It defines a set of directives that control which resources the browser may load for a given page.

When a resource violates the policy — for example, an inline script when script-src does not include 'unsafe-inline' — the browser blocks it and optionally sends a violation report to a URL you specify.

CSP Directives Reference

Each directive controls a specific resource type:

Building Your First CSP

Start with the most restrictive policy possible and relax it only where necessary:

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

This policy allows resources only from your own origin and blocks everything else. It is a strong starting point for applications that do not load third-party resources.

Source Values

Nonce-Based CSP

Nonces are the recommended way to allow inline scripts without using 'unsafe-inline'. Generate a cryptographically random nonce per request, include it in the header and in each script tag:

# Header
Content-Security-Policy: script-src 'nonce-4AEemGb0xJptoIGFP3Nd'

# HTML
<script nonce="4AEemGb0xJptoIGFP3Nd">
  // This script will execute
</script>

<script>
  // This injected script will be blocked
</script>

The nonce must be different on every response. Never use a static nonce — it would defeat the purpose entirely.

Report-Only Mode

Before enforcing a new CSP, deploy it in report-only mode to see what would break without actually breaking it:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-reports; report-to csp-endpoint

Violation reports are sent as JSON POST requests to the specified URI. Monitor these for a week or two, fix any legitimate violations, and then switch to enforcement.

Configuring CSP in Nginx

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" always;

Configuring CSP in Apache

Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"

Common CSP Mistakes

Testing Your CSP

Use our CSP testing tool to analyze your policy for common weaknesses. You can also audit all your security headers at once. For more on the full suite of security headers, see our complete security headers guide.

Try These Tools

CSP Header Validator Security Headers Audit