script-src Directive Explained
Master the script-src CSP directive to control which JavaScript sources your page can execute. Covers 'self', host allowlists, nonces, hashes, and unsafe keywords.
Detailed Explanation
The script-src Directive
script-src is the most critical directive in any Content Security Policy. It controls where JavaScript can be loaded from and whether inline scripts are permitted. Getting script-src right is the primary defense against Cross-Site Scripting attacks.
Basic Syntax
Content-Security-Policy: script-src 'self' https://cdn.example.com
This allows scripts from the same origin and from https://cdn.example.com. All other script sources, including inline scripts, are blocked.
Source Values
| Value | Meaning |
|---|---|
'self' |
Same origin only |
'none' |
Block all scripts |
https://cdn.example.com |
Specific host |
https: |
Any HTTPS source |
'unsafe-inline' |
Allow inline <script> tags and event handlers |
'unsafe-eval' |
Allow eval(), Function(), setTimeout("string") |
'nonce-abc123' |
Allow scripts with matching nonce attribute |
'sha256-... |
Allow scripts whose content matches the hash |
'strict-dynamic' |
Trust scripts loaded by already-trusted scripts |
Why Avoid unsafe-inline
Inline script execution is the primary vector for XSS attacks. When 'unsafe-inline' is present, an attacker who can inject HTML into your page can execute arbitrary JavaScript. Instead, use nonces or hashes to allow specific inline scripts:
<!-- Server generates a unique nonce per request -->
<script nonce="abc123">
console.log("This is allowed by nonce");
</script>
Content-Security-Policy: script-src 'nonce-abc123'
strict-dynamic
The 'strict-dynamic' keyword tells the browser to trust scripts that are dynamically loaded by an already-trusted script. This is useful for applications that use bundlers or script loaders:
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-abc123'
With 'strict-dynamic', host-based allowlists are ignored, and trust propagates through the script dependency chain.
script-src-elem vs script-src-attr
CSP Level 3 introduced script-src-elem (for <script> elements) and script-src-attr (for inline event handlers like onclick). These allow finer-grained control, but script-src remains the primary directive used in most policies.
Use Case
Configuring script-src is the first step when locking down any web application. E-commerce sites need to allow payment provider scripts, marketing sites need tag manager scripts, and SPAs need their bundled JavaScript. Each scenario requires a carefully crafted script-src that balances security with functionality.