Understanding Content Security Policy Fundamentals

Content Security Policy operates through HTTP headers that instruct browsers on which resources can be loaded and executed. The policy is defined using directives that specify allowed sources for different types of content including scripts, styles, images, and more.

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self' https://apis.google.com; 
               style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;">

The primary CSP directives include:

  • default-src: Sets default policy for unspecified directives
  • script-src: Controls script execution sources
  • style-src: Controls stylesheet sources
  • img-src: Controls image sources
  • connect-src: Controls fetch and XMLHttpRequest sources

Practical CSP Implementation Strategies

1. Progressive Policy Implementation

Start with a restrictive policy and gradually expand as needed. This approach minimizes security risks while allowing for necessary functionality.

<!-- Initial restrictive policy -->
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self';">

2. Handling External Resources

When integrating third-party services, properly configure sources to maintain security:

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               script-src 'self' https://cdn.jsdelivr.net https://apis.google.com; 
               style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; 
               img-src 'self' data: https:; 
               font-src 'self' https://fonts.gstatic.com;">

3. Reporting Policy Violations

Implement reporting mechanisms to monitor and debug CSP issues:

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               report-uri /csp-violation-report; 
               report-to /csp-report-endpoint;">

Common CSP Challenges and Solutions

Script Execution Issues

Dynamic script loading often causes CSP violations. Use nonce or hash attributes for inline scripts:

<script nonce="random-nonce-value">
  // Dynamic script content
</script>

<!-- Alternative approach with hash -->
<script src="external-script.js"></script>

Style-Sheet Restrictions

Inline styles are often blocked by CSP. Implement external stylesheets or use unsafe-inline cautiously:

<!-- Instead of inline styles -->
<div style="color: red;">Content</div>

<!-- Use external styles -->
<div class="red-text">Content</div>

Advanced CSP Configuration Patterns

Development vs Production Environments

Different CSP policies for different environments help balance security and development flexibility:

// Development environment - more permissive
const devPolicy = "default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src 'self' 'unsafe-inline';";

// Production environment - strict
const prodPolicy = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self';";

Frame and Plugin Restrictions

Control embedding and plugin execution to prevent clickjacking and malicious content:

<meta http-equiv="Content-Security-Policy" 
      content="frame-ancestors 'self' https://trusted-site.com; 
               plugin-types application/pdf;">

Performance Considerations

CSP Header Implementation

Server-side CSP headers provide better performance than meta tags:

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

Browser Compatibility

Modern browsers support CSP v1 and v2. Use the most recent version:

BrowserCSP SupportVersion
ChromeFull4.0+
FirefoxFull4.0+
SafariFull5.0+
EdgeFull12.0+

Security Testing and Validation

Testing CSP Effectiveness

Use browser developer tools to monitor CSP violations:

// JavaScript to test CSP enforcement
function testCSP() {
  // This will be blocked if CSP is properly configured
  eval("alert('test')"); // Should trigger CSP violation
}

Violation Reporting

Implement comprehensive reporting to identify potential security issues:

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               report-uri /csp-report; 
               report-to csp-endpoint;">

Best Practices for CSP Implementation

1. Start Conservative

Begin with minimal policies and expand only when necessary:

<!-- Start with minimal policy -->
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'; style-src 'self';">

2. Use Nonce for Dynamic Content

For dynamic scripts, use unique nonces per request:

<?php
$nonce = bin2hex(random_bytes(16));
?>
<script nonce="<?php echo $nonce; ?>">
  // Dynamic content
</script>

3. Regular Policy Auditing

Monitor and update policies based on application changes:

# Example monitoring command
curl -H "Content-Security-Policy: default-src 'self'" https://example.com

Common Pitfalls to Avoid

1. Overly Permissive Policies

Avoid using * in critical directives:

<!-- Avoid this -->
<meta http-equiv="Content-Security-Policy" 
      content="script-src *; style-src *;">

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

2. Missing Report URIs

Always implement reporting for proper monitoring:

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; report-uri /csp-report;">

3. Inconsistent Implementation

Maintain consistent CSP across all application pages:

<!-- Ensure all pages have CSP headers -->
<html>
<head>
  <meta http-equiv="Content-Security-Policy" content="default-src 'self';">
</head>
</html>

Learn more with useful resources