Content Security Policy is a security standard that helps prevent cross-site scripting (XSS) and other code injection attacks. However, CSP can be bypassed through various techniques if it's not properly configured.
Content Security Policy is an HTTP header that allows website administrators to control resources the user agent is allowed to load for a given page. It helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks.
CSP works by specifying which domains the browser should consider to be valid sources of executable scripts. A CSP compatible browser will then only execute scripts loaded from these whitelisted domains, ignoring all other scripts (including inline scripts and event-handling HTML attributes).
Directive | Description | Example |
---|---|---|
default-src |
Fallback for other resource types | default-src 'self' |
script-src |
Valid sources for JavaScript | script-src 'self' trusted.com |
style-src |
Valid sources for stylesheets | style-src 'self' 'unsafe-inline' |
img-src |
Valid sources for images | img-src 'self' img.com |
connect-src |
Valid targets for fetch, XHR, WebSocket | connect-src 'self' api.example.com |
font-src |
Valid sources for fonts | font-src 'self' fonts.gstatic.com |
object-src |
Valid sources for plugins | object-src 'none' |
media-src |
Valid sources for audio and video | media-src media.example.com |
frame-src |
Valid sources for frames | frame-src 'self' |
report-uri |
Where to send CSP violation reports | report-uri /csp-report |
'none'
- No URLs match'self'
- Origin the page came from'unsafe-inline'
- Allows inline JavaScript and CSS'unsafe-eval'
- Allows eval() and similar functionsexample.com
- Allows loading resources from example.com*.example.com
- Allows loading resources from any subdomain of example.comhttps:
- Allows loading resources from any https URLnonce-{random}
- Allows a specific script or style tag with the matching nonce attributesha256-{hash}
- Allows a specific script or style whose hash matchesThis demo shows how different CSP configurations can be vulnerable to bypasses.
Click "Test CSP" to see if the selected CSP configuration is vulnerable.
Missing critical directives means the browser will use default values for those not specified, potentially allowing unsafe behaviors.
This section illustrates different methods attackers use to bypass Content Security Policy restrictions.
Click "Test Bypass" to see if the selected technique can bypass the CSP.
AngularJS template injection can bypass CSP restrictions if AngularJS is allowed from a CDN. This works because AngularJS evaluates expressions within curly braces, which doesn't count as JavaScript execution from CSP's perspective.
This section demonstrates how to create a robust Content Security Policy that mitigates bypass techniques.
Click "Test CSP" to see how the secure CSP configuration protects against attacks.
This basic CSP configuration provides protection against XSS by restricting script execution to the same origin. It also prevents the use of dangerous features like object embeds.
Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; font-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'
This policy uses a "deny by default" approach, only allowing resources from your own domain. It explicitly blocks potentially dangerous resources like objects and frames from other origins.
'unsafe-inline'
- it negates much of CSP's XSS protection'unsafe-eval'
- it allows potentially dangerous code evaluation*
wildcards in sources whenever possibledata:
URIs, especially in script-src// Server-side code generates a random nonce for each response const nonce = crypto.randomBytes(16).toString('base64'); // Add the nonce to your CSP header response.setHeader('Content-Security-Policy', `script-src 'self' 'nonce-${nonce}'`); // In your HTML, add the nonce to each script tag <script nonce="<%= nonce %>"> // This inline script will be allowed by CSP console.log('Hello, secure world!'); </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK" crossorigin="anonymous"> </script>
This ensures that external scripts haven't been tampered with. Add this to your CSP:
Content-Security-Policy: ...; require-sri-for script style
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-violation-report
This allows you to collect violation reports without blocking any resources, helping you refine your policy before full enforcement.
strict-dynamic
- Allows scripts loaded by trusted scripts to executeupgrade-insecure-requests
- Automatically upgrades HTTP requests to HTTPSblock-all-mixed-content
- Blocks all mixed (HTTP/HTTPS) contentContent-Security-Policy: script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none'