Skip to content

Conversation

@venkatprasadh
Copy link

Summary 📝

Add per-request CSP nonce support and automatic nonce injection for served SPA index.html so inline boot scripts are allowed without relaxing the Content Security Policy (CSP).


Files Changed 📂

  • koa-security-headers.ts
    • Generate a per-request base64 nonce (crypto.randomBytes).
    • Expose nonce on ctx.state.cspNonce.
    • Inject 'nonce-<value>' into the script-src directive for console and experience Helmet CSP settings.
  • koa-serve-static.ts
    • When serving SPA index.html, inject nonce="..." into inline <script> tags that lack src/nonce so the markup matches the CSP header.

Notes / Disclaimers ⚠️

  • The browser console may show: "Ignoring 'unsafe-inline' within script-src: nonce-source or hash-source specified" if 'unsafe-inline' remains in existing directives; this is expected — remove 'unsafe-inline' from the CSP for a stricter policy.
  • Middleware ordering is important: koa-security-headers must run before the static-serving middleware so ctx.state.cspNonce is available when index.html is patched.

Testing ✅

Manual run (local container / dev):

  1. Start server/container with the updated code.
  2. Request the console page and verify response header contains the nonce:
    • curl -v http://localhost:3001/console (inspect Content-Security-Policy header)
  3. Verify served HTML contains <script nonce="..."> for inline scripts:
    • curl http://localhost:3001/console | grep -i 'nonce='
  4. Open page in browser — confirm CSP inline-script blocked message is gone for allowed inline scripts.
  5. Verified middleware order: security middleware applied before static SPA middleware so nonce is injected.
  6. Confirmed behaviour with and without existing nonce attributes: only inline scripts without src/nonce are modified.

Checklist 📋

Item Status
.changeset (add entry describing this change)  
unit tests (consider adding tests that assert CSP header contains nonce and served index.html contains matching nonce)  
integration tests (optionally add an end-to-end test that fetches header and HTML and asserts match)  
necessary TSDoc comments (added minimal inline comments; expand if desired)  

If you want, I can prepare the .changeset file and a small integration test that fetches the page and asserts header/body nonce equality.

….html - Generate per-request base64 nonce and expose as ctx.state.cspNonce in packages/core/src/middleware/koa-security-headers.ts - Inject 'nonce-<value>' into script-src directives for console & experience CSP (via Helmet) - Modify packages/core/src/middleware/koa-serve-static.ts to add nonce="..." to inline <script> tags (only for scripts without src/nonce) in served index.html - Ensures CSP header nonce matches inline scripts and avoids enabling unsafe-inline

What: Adds a secure per-request CSP nonce and injects that nonce into inline scripts at response time so the browser accepts the inline boot scripts without relaxing CSP.
Files changed:
koa-security-headers.ts — generate nonce, expose ctx.state.cspNonce, inject nonce into script-src for console & experience policies.
koa-serve-static.ts — when serving SPA index.html, add nonce="..." to inline script tags that lack src/nonce.
Verification:
Ensure koa-security-headers middleware runs before static serving middleware.
Request console page and confirm Content-Security-Policy header contains 'nonce-<base64>'.
Confirm served HTML has <script nonce="..."> for inline scripts and browser no longer blocks them.
Disclaimer / notes:
You may see the console warning: "Ignoring 'unsafe-inline' within script-src: nonce-source or hash-source specified" — this is expected if 'unsafe-inline' remains in the directive; it is ignored when nonces/hashes are present. Remove 'unsafe-inline' from CSP for stricter security.
The HTML injection is a pragmatic server-side fix; long-term prefer adding nonce at build-time or moving inline scripts to external files.
Would you like a ready PR description with checklist and commands to run tests/build?
@github-actions
Copy link

github-actions bot commented Nov 8, 2025

COMPARE TO master

Total Size Diff 📈 +2.28 KB

Diff by File
Name Diff
packages/core/src/middleware/koa-security-headers.ts 📈 +1.4 KB
packages/core/src/middleware/koa-serve-static.ts 📈 +900 Bytes

@wangsijie
Copy link
Contributor

Hi, can you please check the CI result and fix the lint issues?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants