A Tempting Shortcut When Things Break
Deploy a new CSP, and it's common to immediately see console errors — inline scripts and event handlers your site actually relies on getting blocked. The fastest fix that makes the errors disappear is adding 'unsafe-inline' to script-src. It's also, almost always, the wrong fix.
Why This Specifically Undoes CSP's Protection
Recall that CSP's single biggest XSS defense is blocking inline scripts by default — since most real-world XSS attacks work by injecting exactly this kind of inline script into a page. Adding 'unsafe-inline' to script-src re-allows inline scripts unconditionally — including any an attacker manages to inject. This doesn't weaken your policy's protection somewhat; it removes the single mechanism responsible for most of CSP's actual XSS-blocking power in the first place.
The Better Fix: Nonces or Hashes
Rather than allowing all inline scripts indiscriminately, a nonce-based policy allows only the specific inline scripts your server explicitly marks as trusted for that page load — a random, unique value generated fresh each time, attached both to the CSP header and to the specific <script> tags you actually intend to run:
Content-Security-Policy: script-src 'nonce-R4nd0m123';
<script nonce="R4nd0m123">
// this script runs -- it has the matching nonce
</script>
An attacker injecting a script has no way to know or predict that fresh, per-request nonce value, so their injected script — lacking the matching nonce — simply doesn't execute, while your legitimate inline scripts, correctly tagged, still work exactly as intended.
An Important Technicality
If your policy includes a nonce or hash expression, browsers automatically ignore any 'unsafe-inline' value present in the same directive — meaning a modern browser correctly enforces the stricter nonce-based rule even if 'unsafe-inline' is still listed as a fallback for older browsers that don't understand nonces at all.
Ready to build a policy using nonces instead?
Open CSP Generator