What Is a CSP Nonce and How Does It Work?
A nonce-based Content Security Policy allows specific inline scripts without using unsafe-inline. This guide explains what a nonce is, how to implement it, and why it is more secure.
ProfitTool Team
Security & Dev
The Problem with unsafe-inline
Inline scripts are a common source of XSS vulnerabilities. Content-Security-Policy: script-src 'unsafe-inline' allows all inline scripts, which significantly weakens the protection CSP offers — an attacker who injects an inline script can execute it.
The alternative to unsafe-inline is a nonce.
What a Nonce Is
A nonce (number used once) is a cryptographically random value generated fresh for every HTTP response. It is included in the CSP header and in the nonce attribute of each script tag you want to allow. The browser only executes inline scripts that carry a nonce matching the value in the CSP header.
Since the nonce is different on every page load, an attacker cannot predict it — injected scripts that do not carry a valid nonce are blocked.
Implementation
Server-side (Node.js example)
import { randomBytes } from 'crypto';
function generateNonce() {
return randomBytes(16).toString('base64');
}
// In your request handler:
const nonce = generateNonce();
res.setHeader(
'Content-Security-Policy',
`script-src 'nonce-${nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none';`
);
// Pass nonce to your template rendererHTML template
<script nonce="<%= nonce %>">
// This script is allowed
document.querySelector('#app').innerHTML = 'Hello';
</script>strict-dynamic
When combined with a nonce, 'strict-dynamic' propagates trust to scripts loaded by trusted scripts:
script-src 'nonce-abc123' 'strict-dynamic'This means a trusted script can document.createElement('script') and load additional scripts without needing nonces on them. Useful for applications that dynamically load modules.
Nonces Are Not Compatible with Caching
Because the nonce must be different on every response, pages using nonces cannot be served from a static cache. This is the main trade-off. For fully static sites, hash-based CSP ('sha256-hash') is an alternative.
Verify your CSP is correctly configured with our Security Headers Checker.
ProfitTool Team
Security & DevWritten and maintained by the ProfitTool team. Where an article references a ProfitTool utility, the behaviour described is the behaviour of the tool on this site — you can open it and check the output yourself.
More from the Knowledge Hub
Content Security Policy (CSP) Explained: How to Prevent XSS
A CSP header tells the browser which scripts, styles and resources it may load, which is what blunts XSS. Directives, nonces, and how to roll one out safely.
Privacy & SecurityHTTP Security Headers Explained: HSTS, CSP, X-Frame-Options and More
HTTP security headers are directives your web server sends to browsers to prevent common attacks like XSS, clickjacking and protocol downgrade. Here is what each one does.
Privacy & SecurityWhat Is Clickjacking and How Does X-Frame-Options Prevent It?
Clickjacking tricks users into clicking on hidden elements overlaid on a legitimate page. The X-Frame-Options header and CSP frame-ancestors directive prevent this attack.