Answer
Content Security Policy (CSP) is a powerful security mechanism used to prevent XSS attacks, data injection attacks, and other types of code injection attacks. CSP reduces the attack surface by limiting which resources (such as scripts, styles, images, fonts, etc.) can be loaded and executed by the browser.
Core Concepts of CSP
Definition: CSP is an HTTP response header that tells the browser which resources can be loaded from which sources. By defining whitelists, CSP can prevent the execution of malicious scripts.
Basic Syntax:
shellContent-Security-Policy: <policy-directive>; <policy-directive>; ...
Main CSP Directives
1. default-src
Sets the default policy for all resource types. If no policy is set for a specific resource type, the value of default-src is used.
shellContent-Security-Policy: default-src 'self';
2. script-src
Controls the source of JavaScript scripts.
shellContent-Security-Policy: script-src 'self' https://trusted.cdn.com;
3. style-src
Controls the source of CSS stylesheets.
shellContent-Security-Policy: style-src 'self' 'unsafe-inline';
4. img-src
Controls the source of images.
shellContent-Security-Policy: img-src 'self' data: https:;
5. connect-src
Controls the source of XMLHttpRequest, WebSocket, EventSource, and other connections.
shellContent-Security-Policy: connect-src 'self' https://api.example.com;
6. font-src
Controls the source of fonts.
shellContent-Security-Policy: font-src 'self' https://fonts.gstatic.com;
7. object-src
Controls the source of <object>, <embed>, <applet> and other elements.
shellContent-Security-Policy: object-src 'none';
8. media-src
Controls the source of <audio>, <video> and other media elements.
shellContent-Security-Policy: media-src 'self' https://media.example.com;
9. frame-src
Controls the source of <frame>, <iframe> and other frame elements.
shellContent-Security-Policy: frame-src 'self' https://trusted-iframe.com;
10. base-uri
Limits the URL that can be used by the <base> element.
shellContent-Security-Policy: base-uri 'self';
11. form-action
Limits the target URL to which forms can be submitted.
shellContent-Security-Policy: form-action 'self';
12. frame-ancestors
Limits which pages can embed the current page in <frame> or <iframe>.
shellContent-Security-Policy: frame-ancestors 'none';
CSP Source Values
1. 'self'
Only allows loading resources from the same origin.
shellContent-Security-Policy: default-src 'self';
2. 'none'
Does not allow loading resources from any source.
shellContent-Security-Policy: object-src 'none';
3. 'unsafe-inline'
Allows inline scripts and styles (not recommended).
shellContent-Security-Policy: script-src 'self' 'unsafe-inline';
4. 'unsafe-eval'
Allows using eval() and similar functions (not recommended).
shellContent-Security-Policy: script-src 'self' 'unsafe-eval';
5. 'strict-dynamic'
Allows scripts loaded by trusted scripts to execute.
shellContent-Security-Policy: script-src 'self' 'strict-dynamic';
6. 'report-sample'
Includes sample code in violation reports.
shellContent-Security-Policy: script-src 'self' 'report-sample';
7. Specific Domain
Allows loading resources from a specific domain.
shellContent-Security-Policy: script-src 'self' https://cdn.example.com;
8. Wildcard
Allows loading resources from any subdomain.
shellContent-Security-Policy: script-src 'self' https://*.example.com;
9. Protocol Restriction
Allows loading resources from a specific protocol.
shellContent-Security-Policy: img-src https:;
How CSP Prevents XSS Attacks
1. Blocks Inline Script Execution
Unsafe Page:
html<script> alert('XSS'); </script>
Protection with CSP:
shellContent-Security-Policy: script-src 'self';
Result: Inline scripts will be blocked from execution.
2. Blocks eval Execution
Unsafe Code:
javascripteval('alert("XSS")');
Protection with CSP:
shellContent-Security-Policy: script-src 'self';
Result: eval() calls will be blocked.
3. Limits External Script Sources
Unsafe Page:
html<script src="https://malicious.com/script.js"></script>
Protection with CSP:
shellContent-Security-Policy: script-src 'self' https://trusted.cdn.com;
Result: Scripts from malicious domains will be blocked from loading.
4. Blocks Dynamic Script Injection
Unsafe Code:
javascriptconst script = document.createElement('script'); script.src = 'https://malicious.com/script.js'; document.body.appendChild(script);
Protection with CSP:
shellContent-Security-Policy: script-src 'self';
Result: Dynamically injected scripts will be blocked from loading.
CSP Implementation Methods
1. Through HTTP Response Header
Node.js Express Example:
javascriptapp.use((req, res, next) => { res.setHeader( 'Content-Security-Policy', "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;" ); next(); });
Nginx Configuration Example:
nginxadd_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;";
Apache Configuration Example:
apacheHeader always set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:"
2. Through HTML meta Tag
html<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self';">
Note: The meta tag approach is less secure than the HTTP response header because some attacks may bypass the meta tag.
CSP Report-Only Mode
Before implementing CSP, you can use Report-Only mode to test the policy without blocking any resource loading.
shellContent-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report
Report Endpoint Example:
javascriptapp.post('/csp-report', (req, res) => { console.log('CSP Violation:', req.body); res.status(204).end(); });
CSP Violation Reports
When a CSP policy is violated, the browser sends a violation report to the specified endpoint.
Report Format Example:
json{ "csp-report": { "document-uri": "http://example.com/page.html", "referrer": "http://example.com/", "violated-directive": "script-src", "effective-directive": "script-src", "original-policy": "default-src 'self'; script-src 'self'", "disposition": "report", "blocked-uri": "https://malicious.com/script.js", "line-number": 10, "column-number": 5, "source-file": "http://example.com/page.html", "status-code": 200, "script-sample": "" } }
CSP Best Practices
1. Start with a Strict Policy
shellContent-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; base-uri 'self'; form-action 'self';
2. Gradually Relax the Policy
Add allowed sources based on actual needs.
shellContent-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;
3. Avoid Using 'unsafe-inline' and 'unsafe-eval'
Not Recommended:
shellContent-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval';
Recommended:
shellContent-Security-Policy: script-src 'self' 'nonce-abc123';
4. Use Nonce or Hash
Nonce Example:
html<script nonce="abc123"> // This script will be allowed to execute </script>
shellContent-Security-Policy: script-src 'self' 'nonce-abc123';
Hash Example:
html<script> alert('Hello'); </script>
shellContent-Security-Policy: script-src 'self' 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=';
5. Use report-uri to Monitor Violations
shellContent-Security-Policy: default-src 'self'; script-src 'self'; report-uri /csp-report
6. Regularly Review and Update the Policy
Regularly check CSP violation reports and adjust the policy based on actual conditions.
Limitations of CSP
1. Not Fully Compatible with Old Browsers
Older browser versions may not support CSP or have incomplete support.
2. May Affect Functionality
Strict CSP policies may block some legitimate features, such as third-party analytics tools, ads, etc.
3. Cannot Completely Replace Other Security Measures
CSP cannot replace input validation, output encoding, and other security measures.
4. Complex Configuration
Properly configuring CSP requires a deep understanding of the application's resource dependencies.
Real-world Cases
Case 1: Preventing Stored XSS
javascript// Server-side set CSP app.use((req, res, next) => { res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self';"); next(); }); // Even if attackers inject malicious scripts in the comment section // <script>alert('XSS')</script> // The browser will block script execution
Case 2: Preventing Reflected XSS
javascript// Server-side set CSP app.use((req, res, next) => { res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self';"); next(); }); // Even if attackers construct malicious URLs // http://example.com/search?q=<script>alert('XSS')</script> // The browser will block script execution
Case 3: Preventing DOM-based XSS
javascript// Server-side set CSP app.use((req, res, next) => { res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self';"); next(); }); // Even if there are unsafe DOM operations on the page // document.getElementById('output').innerHTML = location.hash; // The browser will block inline script execution
Summary
Content Security Policy is a powerful tool for preventing XSS attacks. It effectively reduces the risk of XSS attacks by limiting resource sources and blocking unsafe script execution. Best practices for implementing CSP include:
- Start with a strict policy and gradually relax it
- Avoid using 'unsafe-inline' and 'unsafe-eval'
- Use nonce or hash to allow specific inline scripts
- Use report-only mode to test the policy
- Regularly review and update the policy
- Use CSP as part of a multi-layered defense strategy
Although CSP cannot completely replace other security measures, it is an indispensable part of modern web application security architecture.