
HTML Security: Implementing Content Security Policy (CSP) for Modern Web Applications
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 directivesscript-src: Controls script execution sourcesstyle-src: Controls stylesheet sourcesimg-src: Controls image sourcesconnect-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:
| Browser | CSP Support | Version |
|---|---|---|
| Chrome | Full | 4.0+ |
| Firefox | Full | 4.0+ |
| Safari | Full | 5.0+ |
| Edge | Full | 12.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.comCommon 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>