Content Security Policy (CSP)

Defending against unwanted resources in web applications

What is CSP?

Content Security Policy (CSP) is an HTTP header that allows developers to control which resources (scripts, styles, frames) are allowed to load in a web application. It acts as a defense mechanism against XSS by mitigating the impact of compromised code.

Key Benefit: CSP prevents unauthorized scripts from executing even if the application is already compromised.

How CSP Works

Content Sources

  • 'self' - Allow resources from the same origin
  • 'unsafe-inline' - Permit inline scripts/styles
  • 'none' - Block all resources
  • Custom domains/IPs with HTTPS
  • Hash values for specific content

Directive Categories

  • default-src - Fallback policy
  • script-src - Script loading
  • style-src - Stylesheet rules
  • connect-src - API requests
  • img-src - Image sources

Implementing CSP

HTTP Header (Recommended)

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'

Or use a <meta> tag as a fallback (less preferred for production):

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted-cdn.com">

Security Configuration Examples

Secure Configuration

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-cdn.com; img-src 'self' data:; font-src 'self'; connect-src 'self'

Development Configuration

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src *

Note: 'unsafe-eval' should be removed before production

Security Recommendations

Proven Strategies

  • Start with 'self' for all directives
  • Use nonce-based policies for critical resources
  • Monitor violations using the report-uri directive
  • Apply strict-dynamic for script execution contexts
  • Use a nonce generator for unique script identifiers

Common Pitfalls

  • Reliance on 'unsafe-inline' or 'unsafe-eval'
  • Overly broad default-src without specific rules
  • Ignoring Content Security Policy Report Only (CSP-Report-Only)
  • Failing to update policies after CDN/service changes
  • Not validating third-party resource origins