Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
Allowlists inline scripts and styles under Content Security Policy. A unique server-generated token per request that prevents unauthorized code injection.
The nonce attribute allows specific inline <script> and <style> elements to execute under a Content Security Policy (CSP) that otherwise blocks all inline code. The server generates a unique, unpredictable token for each HTTP response, places it in both the CSP header and the allowed elements, and the browser only executes inline code whose nonce matches.
Without nonces (or hashes), a strict CSP must either block all inline scripts — breaking many applications — or use 'unsafe-inline', which defeats the purpose of CSP entirely.
Content-Security-Policy header: script-src 'nonce-VALUE'.nonce="VALUE" to every trusted inline <script> and <style> tag in the response.element.getAttribute('nonce').<!-- Server generates a unique nonce for each HTTP response --><!-- CSP header: Content-Security-Policy: script-src 'nonce-abc123random' --> <!-- This inline script is allowed because its nonce matches the CSP header --><script nonce="abc123random"> document.title = 'Page loaded securely';</script> <!-- This inline style is allowed for the same reason --><!-- CSP header: Content-Security-Policy: style-src 'nonce-abc123random' --><style nonce="abc123random"> body { font-family: system-ui; }</style>
The nonce value in the CSP header must be prefixed with nonce- and wrapped in single quotes.
# CSP header allowing nonce-based inline scripts and stylesContent-Security-Policy: script-src 'nonce-rAnd0mV4luE' 'strict-dynamic'; style-src 'nonce-rAnd0mV4luE' # Combined with other directivesContent-Security-Policy: default-src 'self'; script-src 'nonce-rAnd0mV4luE' 'strict-dynamic'; style-src 'nonce-rAnd0mV4luE'; img-src 'self' https:
The nonce must be generated server-side and must be unique per request. Use a cryptographically secure random number generator.
# Express.js — generate nonce per requestimport crypto from 'crypto'; app.use((req, res, next) => { const nonce = crypto.randomBytes(16).toString('base64'); res.locals.nonce = nonce; res.setHeader( 'Content-Security-Policy', `script-src 'nonce-${nonce}' 'strict-dynamic'; style-src 'nonce-${nonce}'` ); next();}); # In your template:# <script nonce="<%= nonce %>">...</script>
The 'strict-dynamic' CSP directive works with nonces to create a trust chain. Scripts loaded dynamically by a nonced script are automatically trusted, even without their own nonce attribute. This simplifies CSP for applications that load third-party scripts at runtime.
<!-- With 'strict-dynamic' in the CSP, scripts loaded BY a nonced script --><!-- are automatically trusted, even without their own nonce. --> <!-- CSP: script-src 'nonce-abc123' 'strict-dynamic' --><script nonce="abc123"> // This dynamically added script is trusted because the parent has a nonce const s = document.createElement('script'); s.src = '/js/analytics.js'; document.head.appendChild(s);</script>
CSP can be set via a <meta> tag instead of an HTTP header. However, the HTTP header is preferred because it cannot be bypassed by injected HTML before the meta tag.
<!-- CSP can also be set via a meta tag (but HTTP header is preferred) --><meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc123random'; style-src 'nonce-abc123random'" /> <script nonce="abc123random"> console.log('Allowed by meta CSP');</script>
Cache-Control: no-store on pages with nonces.element.nonce returns the value via the IDL property, but element.getAttribute('nonce') returns an empty string. This prevents injected scripts from reading the nonce out of existing elements.nonce attribute only affects inline code. Use 'strict-dynamic' or explicit URL allowlists for external script sources.onclick. Move event handling to nonced script blocks.integrity — verify external script and stylesheet contentscrossorigin — CORS mode required alongside SRIsandbox — iframe restrictions that complement CSP