Use CSP (Content Security Policy) to prevent XSS
What is CSP
CSP (Content Security Policy) is a browser-implemented security mechanism designed to detect and mitigate certain types of attacks, including cross-site scripting (XSS) and data injection attacks. It works by defining the allowed sources for loading resources, restricting the browser to only execute or render resources from these sources. The core idea of CSP is a whitelist mechanism, where developers explicitly tell the browser which resources can be loaded, while all others are blocked.
How CSP Protects Against XSS
XSS attacks typically involve injecting malicious scripts into web pages for execution. CSP effectively prevents XSS in the following ways:
- Blocking Inline Script Execution: By default, CSP prevents inline code in
<script>
tags andjavascript:
pseudo-protocols. - Restricting Script Sources: Only allows loading script files from specific domains.
- Blocking eval-like Functions: Disables dynamic code execution methods such as
eval()
andsetTimeout(string)
. - Restricting Non-Static Resources: Controls the loading sources for fonts, frames, images, and other resources.
Three Ways to Implement CSP
Via HTTP Headers
The most recommended method is to set it through HTTP response headers:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src *; media-src media1.com media2.com; report-uri /csp-violation-report-endpoint
Via Meta Tag
Useful when server configuration cannot be modified:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
Via Report-Only Mode
Monitors without enforcement, suitable for debugging:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-violation-report-endpoint
Detailed Explanation of CSP Directives
Common Directives
default-src
: Default policy for directives not explicitly specified.script-src
: Controls JavaScript loading sources.style-src
: Controls CSS loading sources.img-src
: Controls image loading sources.connect-src
: Controls sources for XHR, WebSocket, etc.font-src
: Controls font file loading sources.object-src
: Controls tags like<object>
,<embed>
, and<applet>
.media-src
: Controls media resources like<audio>
and<video>
.frame-src
: Controls<iframe>
loading sources (deprecated, replaced bychild-src
).child-src
: Controls child contexts (e.g., iframe, worker).worker-src
: Controls worker, shared worker, and service worker sources.
Special Values
'none'
: Blocks all resources.'self'
: Allows only same-origin resources.'unsafe-inline'
: Allows inline scripts/styles (reduces security).'unsafe-eval'
: Allows dynamic code execution (e.g.,eval
).'strict-dynamic'
: Trusts scripts dynamically loaded by already executed scripts.'nonce-<base64-value>'
: Allows specific inline scripts using a one-time random value.'sha256-<hash-value>'
: Allows specific inline scripts using a hash value.
Practical CSP Configuration Examples
Basic Security Configuration
Content-Security-Policy:
default-src 'none';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
form-action 'self';
frame-ancestors 'none';
base-uri 'self';
report-uri /csp-report
Strict Configuration (Recommended)
Content-Security-Policy:
default-src 'none';
script-src 'self' https://cdn.example.com;
style-src 'self';
img-src 'self' data: https://*.example-cdn.com;
font-src 'self';
connect-src 'self' https://api.example.com;
form-action 'self';
frame-ancestors 'none';
base-uri 'self';
report-uri /csp-report
Configuration Allowing Google Analytics
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.google-analytics.com 'unsafe-inline';
img-src 'self' https://www.google-analytics.com;
style-src 'self' 'unsafe-inline';
connect-src 'self' https://www.google-analytics.com;
report-uri /csp-report
Handling Inline Scripts and Styles
Using Nonce
The server generates a random value and injects it into the CSP header and script tag:
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
// This script will execute
</script>
<script>
// This script will be blocked
</script>
Using Hash
Calculate the SHA hash of the script content and add it to CSP:
Content-Security-Policy: script-src 'sha256-abc123...'
<script>
// The content must exactly match the hash calculation
alert('Hello, world.');
</script>
CSP Reporting Mechanism
Violation Report Configuration
Content-Security-Policy: default-src 'self'; report-uri /csp-report-endpoint
Example Report (POST Data)
{
"csp-report": {
"document-uri": "https://example.com/page.html",
"referrer": "https://example.com/",
"violated-directive": "style-src 'self'",
"effective-directive": "style-src",
"original-policy": "default-src 'self'; style-src 'self'",
"disposition": "enforce",
"blocked-uri": "https://evil.com/malicious.css",
"line-number": 10,
"column-number": 20,
"source-file": "https://example.com/page.html",
"status-code": 200,
"script-sample": ".evil { color: red; }"
}
}
Common Issues and Solutions
Third-Party Integration Issues
Issue: CSP errors when using third-party libraries (e.g., jQuery, Bootstrap).
Solutions:
- Host the library on your own server and use
'self'
. - Add the CDN address to the whitelist:
script-src 'self' https://code.jquery.com
- Use Subresource Integrity (SRI):
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha384-KyZXEAg3QhqLMpG8r+Knujsl5/1EN..." crossorigin="anonymous"></script>
Inline Event Handler Issues
Issue: HTML event handlers like onclick
are blocked.
Solutions:
- Use external scripts to add event listeners:
document.getElementById('myButton').addEventListener('click', function() { // Handle click });
- Use
'unsafe-inline'
(not recommended). - Use CSP Level 3's
'unsafe-hashes'
.
Dynamic Style Issues
Issue: JavaScript dynamically modifying styles is blocked.
Solutions:
- Switch to class toggling instead of direct style modification:
element.classList.add('active');
- Use
'unsafe-inline'
or hashes/nonces.
CSP and Modern Frontend Frameworks
React App Configuration
React requires 'unsafe-inline'
for its event system:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self' https://api.example.com;
Vue App Configuration
Vue requires 'unsafe-eval'
for template compilation:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
Angular App Configuration
Angular requires 'unsafe-eval'
for JIT compilation:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
For AOT-compiled Angular apps, 'unsafe-eval'
can be removed.
CSP Deployment Strategies
Phased Deployment
- Reporting Phase: Use
Content-Security-Policy-Report-Only
to monitor potential issues. - Loose Policy: Initially allow necessary
'unsafe-inline'
and'unsafe-eval'
. - Strict Policy: Gradually remove unsafe options, replacing them with nonces/hashes.
- Continuous Optimization: Adjust policies based on reports.
Monitoring and Maintenance
- Set up a reporting endpoint to collect violation data.
- Regularly review CSP reports.
- Adjust CSP policies as the application evolves.
- Use automated tools to test CSP effectiveness.
Advanced CSP Techniques
Using strict-dynamic
Content-Security-Policy: script-src 'nonce-abc123' 'strict-dynamic'
Allows scripts dynamically loaded by trusted scripts to execute, suitable for modern modular applications.
Multiple CSP Policies
Multiple CSP headers can be combined, with policies enforcing cumulative restrictions:
Content-Security-Policy: script-src 'self'
Content-Security-Policy: script-src https://cdn.example.com
The final policy is script-src 'self' https://cdn.example.com
.
Preload Directives
Content-Security-Policy:
default-src 'self';
script-src 'self';
preload-src 'self' https://cdn.example.com
Controls sources for <link rel="preload">
resources.
CSP Synergy with Other Security Mechanisms
Combined with Subresource Integrity (SRI)
<script src="https://example.com/script.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
Combined with Feature Policy
Content-Security-Policy: default-src 'self'
Feature-Policy: geolocation 'none'; microphone 'none'
Combined with Expect-CT
Content-Security-Policy: default-src 'self'
Expect-CT: max-age=86400, enforce, report-uri="https://example.com/report"
Limitations of CSP
- Browser Compatibility: Varying levels of CSP support across browsers.
- Configuration Complexity: Strict CSP may require refactoring existing code.
- False Positives: Overly strict policies may block legitimate resources.
- Performance Impact: Complex policies may increase browser processing time.
- Not a Panacea: Does not protect against CSRF, SQL injection, or other attacks.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn