Content Security Policy (CSP)

A security layer that helps prevent cross-site scripting (XSS), data injection attacks, and other malicious content execution in web browsers.

What is Content Security Policy (CSP)?

Content Security Policy (CSP) is a browser security mechanism that helps prevent cross-site scripting (XSS), data injection attacks, and other content execution vulnerabilities by defining and enforcing rules about what resources a web page can load and execute. CSP acts as an additional layer of security that works alongside other web security measures to mitigate the impact of potential vulnerabilities.

CSP is implemented through an HTTP response header or meta tag that specifies approved sources for various types of content, effectively creating a whitelist of trusted origins.

How CSP Works

  1. Policy Definition: Website administrator defines CSP rules in HTTP headers or meta tags
  2. Policy Delivery: Browser receives CSP directives with the web page response
  3. Resource Loading: Browser attempts to load resources (scripts, images, styles, etc.)
  4. Policy Enforcement: Browser checks each resource against CSP rules
  5. Action: Browser blocks resources that violate CSP directives
  6. Reporting: Browser can report violations to a specified endpoint (optional)

Key CSP Directives

Resource Control Directives

  • default-src: Fallback for other directives
  • script-src: Controls JavaScript sources
  • style-src: Controls CSS sources
  • img-src: Controls image sources
  • font-src: Controls font sources
  • connect-src: Controls connection sources (AJAX, WebSocket, etc.)
  • media-src: Controls audio and video sources
  • object-src: Controls plugins (Flash, Java, etc.)
  • frame-src: Controls frame/iframe sources
  • child-src: Controls web workers and nested browsing contexts

Document Directives

  • base-uri: Restricts URLs for the document's base element
  • form-action: Restricts URLs for form submissions
  • frame-ancestors: Replaces X-Frame-Options for frame embedding control
  • navigate-to: Restricts URLs to which a document can navigate

Reporting Directives

  • report-uri: Specifies where violation reports should be sent
  • report-to: Modern replacement for report-uri (uses Report-To header)

Other Directives

  • sandbox: Applies sandbox restrictions to the page
  • upgrade-insecure-requests: Upgrades HTTP requests to HTTPS
  • block-all-mixed-content: Blocks mixed content (HTTP in HTTPS pages)
  • require-sri-for: Requires Subresource Integrity for specified resource types

CSP Levels and Versions

VersionKey FeaturesStatus
CSP Level 1Basic directives, initial implementationObsolete
CSP Level 2Nonce support, hash support, frame-ancestorsWidely supported
CSP Level 3Strict-dynamic, report-to, navigate-to, webrtcCurrent standard
CSP NextFuture enhancements, experimental featuresIn development

Implementation Methods

HTTP Header

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; img-src 'self' data:; report-uri https://example.com/csp-report-endpoint

Meta Tag

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

Common CSP Use Cases

Preventing XSS Attacks

  • Restrict inline scripts with 'unsafe-inline'
  • Require nonces or hashes for script execution
  • Block eval() and similar functions with 'unsafe-eval'

Securing Third-Party Content

  • Whitelist specific CDNs and external domains
  • Implement Subresource Integrity (SRI) for external resources
  • Restrict mixed content with upgrade-insecure-requests

Controlling Frame Embedding

  • Use frame-ancestors to prevent clickjacking
  • Restrict embedding to specific domains or block entirely

Monitoring Security Violations

  • Implement report-uri or report-to to collect violation reports
  • Monitor for attempted attacks and misconfigurations

CSP Keywords and Values

Keyword/ValueDescription
'none'Blocks all resources of the specified type
'self'Allows resources from the same origin
'unsafe-inline'Allows inline scripts/styles (not recommended)
'unsafe-eval'Allows eval() and similar functions (not recommended)
'strict-dynamic'Allows scripts loaded by trusted scripts to execute
'nonce-<value>'Allows scripts/styles with matching nonce attribute
'sha256-<hash>'Allows scripts/styles with matching SHA-256 hash
'sha384-<hash>'Allows scripts/styles with matching SHA-384 hash
'sha512-<hash>'Allows scripts/styles with matching SHA-512 hash
data:Allows data URIs (use with caution)
blob:Allows blob URIs
mediastream:Allows mediastream URIs

CSP vs. Other Security Headers

HeaderPurposeRelationship to CSP
Content Security Policy (CSP)Controls resource loading and executionPrimary security mechanism
X-Frame-OptionsControls frame embeddingReplaced by CSP's frame-ancestors
X-Content-Type-OptionsPrevents MIME sniffingComplements CSP
HTTP Strict Transport SecurityEnforces HTTPSWorks alongside CSP
Referrer-PolicyControls referrer informationIndependent but complementary

Real-World Examples

  • Twitter: Implemented CSP to prevent XSS attacks and reduce security risks
  • GitHub: Uses CSP with strict-dynamic and nonce-based script execution
  • Google: Implements CSP across various services to enhance security
  • Facebook: Uses CSP to control third-party content and prevent data exfiltration
  • Financial Institutions: Banks use CSP to secure online banking platforms
  • E-commerce Sites: Use CSP to protect payment processing and customer data

Implementation Challenges

Common Issues

  • Inline Scripts/Styles: Legacy code often relies on inline scripts/styles
  • Third-Party Dependencies: External libraries may violate CSP rules
  • Dynamic Content: JavaScript frameworks that generate dynamic content
  • Browser Compatibility: Different browsers support different CSP features
  • Performance Impact: Additional checks may impact page load times
  • Debugging Complexity: Violations can be difficult to diagnose

Best Practices for Implementation

  1. Start with Report-Only Mode: Use Content-Security-Policy-Report-Only to monitor violations
  2. Gradual Rollout: Implement CSP in stages, starting with permissive policies
  3. Use Nonces/Hashes: Replace 'unsafe-inline' with nonces or hashes
  4. Monitor Violations: Set up reporting to collect and analyze CSP violations
  5. Test Thoroughly: Test across different browsers and devices
  6. Document Policies: Maintain documentation of CSP rules and exceptions
  7. Educate Developers: Train developers on CSP-compliant coding practices
  8. Automate Enforcement: Use build tools to generate and validate CSP headers

CSP Reporting

Report-Only Mode

Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://example.com/csp-report-endpoint

Violation Report Format

{
  "csp-report": {
    "document-uri": "https://example.com/page.html",
    "referrer": "https://example.com/",
    "violated-directive": "script-src 'self'",
    "effective-directive": "script-src",
    "original-policy": "default-src 'self'; script-src 'self' https://trusted.cdn.com; report-uri https://example.com/csp-report-endpoint",
    "disposition": "enforce",
    "blocked-uri": "https://evil.com/malicious.js",
    "line-number": 42,
    "column-number": 12,
    "source-file": "https://example.com/page.html",
    "status-code": 200,
    "script-sample": "alert('XSS')"
  }
}

Advanced CSP Features

Strict CSP

Content-Security-Policy: script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none'

Trusted Types

Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default

CSP with Service Workers

// In service worker
self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request).then(response => {
      // Modify CSP headers for responses
      const newHeaders = new Headers(response.headers);
      newHeaders.set('Content-Security-Policy', "default-src 'self'");
      return new Response(response.body, {
        status: response.status,
        statusText: response.statusText,
        headers: newHeaders
      });
    })
  );
});

Industry-Specific Considerations

IndustryCSP ConsiderationsPotential Challenges
FinanceStrict policies for payment processingLegacy banking systems
HealthcareHIPAA compliance, patient data protectionThird-party health tools
E-commercePayment gateway security, customer dataMarketing trackers, analytics
GovernmentClassified information protectionLegacy government systems
MediaContent distribution, advertisingThird-party ad networks
TechnologyAPI security, SaaS platformsDynamic content generation
EducationStudent data protectionLearning management systems
  • GDPR: CSP can help demonstrate security measures for data protection
  • PCI DSS: CSP is recommended for securing payment card data
  • HIPAA: CSP can support compliance with health data security requirements
  • FISMA: CSP may be required for federal information systems
  • Industry Standards: CSP aligns with various security best practices

Future of CSP

  • More Granular Control: Additional directives for emerging web technologies
  • Better Integration: Improved integration with web frameworks and build tools
  • Enhanced Reporting: More detailed and actionable violation reports
  • Automated Enforcement: AI-powered policy generation and enforcement
  • Browser Improvements: Better developer tools for CSP debugging
  • Standardization: Continued evolution of the CSP specification

Best Practices for CSP Implementation

  1. Start with report-only mode to monitor violations without breaking functionality
  2. Use nonces or hashes instead of 'unsafe-inline' for scripts and styles
  3. Implement strict-dynamic for modern JavaScript applications
  4. Set up violation reporting to monitor and respond to security incidents
  5. Regularly review and update CSP policies as your application evolves
  6. Test across browsers to ensure consistent behavior
  7. Combine with other security headers for layered defense
  8. Educate developers about CSP-compliant coding practices
  9. Use build tools to automate CSP header generation
  10. Monitor performance impact and optimize policies as needed