
How to Safely Allow Inline Scripts Without Breaking Security with CSP Nonce
Get the Weekly Digest in your inbox
430+ newsletter subscribers. Curated Vue and Nuxt news every week — articles, releases, and conferences.
Topics

From the source
When building modern web applications, security is not optional. One of the most important protections you can add is a Content Security Policy (CSP). But here’s the catch: 👉 CSP often blocks inline scripts and styles — which can break your app. So how do you keep your app secure without disabling useful features? That’s where CSP nonce comes in - it allows you to safely execute inline code without opening security holes. In this article, we’ll explore: What CSP nonce is What problem it solves How to implement it How it works automatically in Nuxt with nuxt-security Best practices and common pitfalls Let’s dive in. 🤔 What Is CSP Nonce? A nonce (short for number used once) is a unique, random value generated for each request. It is used in CSP to explicitly allow trusted inline scripts or styles. Example: <script nonce="abc123"> console.log('Secure inline script') </script> And in your HTTP headers: Content-Security-Policy: script-src 'nonce-abc123' The browser will only execute scripts that have a matching nonce. CSP nonce is a whitelist mechanism: Only scripts with the correct nonce are allowed Everything else is blocked The nonce changes on every request This makes it extremely effective against XSS (Cross-Site Scripting) attacks. CSP nonce is commonly used for: SSR frameworks - Injecting initial state, Hydration scripts Analytics / tracking snippets - Inline scripts required by providers Critical inline scripts - Small scripts needed before app bootstraps 🟢 What Problem Does CSP Nonce Solve? Without nonce, you usually face a trade-off: ❌ Allow inline scripts (unsafe) Content-Security-Policy: script-src 'unsafe-inline' Problem: Opens the door to XSS attacks Any injected script can run ❌ Block inline scripts completely Content-Security-Policy: script-src 'self' Problem: breaks inline event handlers breaks injected scripts (SSR hydration, state) breaks some frameworks 🟢 How to Implement CSP Nonce The process is relatively simple but let's break it down and explain each step individually. Step 1: Generate a nonce per request Example (Node.js): import crypto from 'crypto' function generateNonce() { return crypto.randomBytes(16).toString('base64') } Step 2: Add it to response headers const nonce = generateNonce() res.setHeader( 'Content-Security-Policy', `script-src 'nonce-${nonce}'` ) Step 3: Inject it into your HTML <script nonce="{{nonce}}"> window.__INITIAL_STATE__ = {} </script> ⚠️ Critical rule The nonce in the header and HTML must match exactly. Otherwise, script will be blocked and app may break silently. 🟢 CSP Nonce in Nuxt (with nuxt-security) If you’re using Nuxt, things get much easier thanks to nuxt-security module that can: Automatically generate nonce per request Inject it into CSP headers Attach it to scripts/styles It makes it much easier to work with CSP nonces in Nuxt. Let's take a look at the following configuration: export default defineNuxtConfig({ modules: ['nuxt-security'], security: { headers: { contentSecurityPolicy: { 'script-src': [ "'self'", "'nonce-{{nonce}}'" ] } } } }) What happens automatically: Nuxt generates a nonce per request Replaces {{nonce}} in headers Applies nonce to inline scripts You don’t need to manually wire everything You can read more here: https://nuxt-security.vercel.app/ 🟢 Common Mistakes Let's take a look at the list of common mistakes to understand what to look for: ❌ Reusing the same nonce - Nonce must be unique per request and cryptographically random ❌ Forgetting to apply nonce in HTML - if you only set CSP header the scripts will still be blocked ❌ Mixing nonce with unsafe-inline - script-src 'unsafe-inline' 'nonce-abc' ❌ Caching issues - if HTML is cached nonce may not match header 🧪 Best Practices Generate nonce per request Use secure randomness (crypto) Never reuse nonce Avoid unsafe-inline Use frameworks/tools (like nuxt-security) Test CSP in report-only mode first Monitor browser console for CSP violations 📖 Learn more If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below: It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉 🧪 Advance skills A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success. Check out Certificates.dev by clicking this link or by clicking the image below: Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more! ✅ Summary CSP nonce is a powerful mechanism that allows you to safely use inline scripts while maintaining strong security. In this article, you learned: What CSP nonce is and how it works What problem it solves (security vs flexibility) How to implement it step by step How Nuxt + nuxt-security handle it automatically Common mistakes and best practices Take care! And happy coding as always 🖥️
Continue reading on the original site

