{"record":{"id":"3139a65043d652da","repo":"quasarframework/quasar","slug":"invalid-ssr-nonce-expected-a-non-empty-base64-or","errorCode":null,"errorMessage":"Invalid SSR nonce. Expected a non-empty base64 or base64url value.","messagePattern":"Invalid SSR nonce\\. Expected a non-empty base64 or base64url value\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"app-vite/templates/entry/ssr-nonce.js","lineNumber":19,"sourceCode":"const nonceRE = /^[A-Za-z0-9+/_-]+={0,2}$/\nconst htmlCharsRE = /[&<>\"']/g\nconst encodeHtmlChars = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;'\n}\n\nexport function injectNonceAttr(ssrContext) {\n  const { nonce } = ssrContext\n  if (!nonce) {\n    ssrContext.__quasarNonceAttr = ''\n    return\n  }\n\n  if (typeof nonce !== 'string' || !nonceRE.test(nonce)) {\n    throw new TypeError(\n      'Invalid SSR nonce. Expected a non-empty base64 or base64url value.'\n    )\n  }\n\n  const value = nonce.replaceAll(htmlCharsRE, char => encodeHtmlChars[char])\n  ssrContext.__quasarNonceAttr = ` nonce=\"${value}\"`\n}\n","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/quasarframework/quasar/blob/4841521b5f635a971eb9e2710e5542efd194691b/app-vite/templates/entry/ssr-nonce.js#L1-L27","documentation":"injectNonceAttr copies a CSP nonce into the SSR render context so rendered tags get a nonce attribute. It throws a TypeError when the provided nonce is not a non-empty string matching the base64/base64url pattern (nonceRE), because a malformed nonce would produce an invalid Content-Security-Policy header or enable markup injection.","triggerScenarios":"Setting an SSR nonce via configuration/env (the value consumed by renderSsrContext, #runVite or renderSsgPage) that is empty, undefined-as-string with wrong chars, contains '<', '\"' or other non-base64 characters, or is not a string at all.","commonSituations":"Generating a nonce with crypto.randomBytes without .toString('base64'/'base64url'); passing a hex-encoded nonce; middleware reading an empty CSP nonce header from upstream; accidentally HTML-escaping the nonce before handing it over.","solutions":["Generate the nonce with crypto.randomBytes(16).toString('base64') (or 'base64url')","Verify the value reaches the app non-empty (log it in dev) — empty nonces are allowed (no attribute) but whitespace/junk is not","Strip quotes/whitespace and any surrounding markup from upstream-provided nonces","Do not pre-HTML-escape the nonce; the helper escapes HTML characters itself"],"exampleFix":"// before\nconst nonce = crypto.randomBytes(16).toString('hex') // invalid: hex not base64\n// after\nconst nonce = crypto.randomBytes(16).toString('base64')","handlingStrategy":"type-guard","validationCode":"const nonceRE = /^[A-Za-z0-9+/_-]+={0,2}$/\nfunction isValidNonce(nonce) {\n  return typeof nonce === 'string' && nonceRE.test(nonce)\n}\nif (nonce != null && !isValidNonce(nonce)) throw new TypeError('nonce must be base64/base64url')","typeGuard":"function isValidNonce(v) {\n  return typeof v === 'string' && /^[A-Za-z0-9+/_-]+={0,2}$/.test(v)\n}","tryCatchPattern":"try {\n  await ssrRender({ nonce })\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes('Invalid SSR nonce')) {\n    // regenerate the nonce: crypto.randomBytes(16).toString('base64')\n  } else throw err\n}","preventionTips":["Always generate nonces via crypto.randomBytes(n).toString('base64') or 'base64url'","Never pass hex-encoded or pre-HTML-escaped values as nonces","Empty string is permitted (means no nonce attribute); sanitize upstream headers before use","Add a startup assertion validating the nonce in dev mode"],"tags":["ssr","csp","security","validation"],"backgroundTag":"invalid-csp-nonce","analyzedSha":"4841521b5f635a971eb9e2710e5542efd194691b","analyzedAt":"2026-08-30T01:13:14.944Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}