feat: Nonce-based CSP implementation

Summary

DRAFT - Work in Progress

This MR implements nonce-based Content Security Policy, which provides significantly stronger XSS protection compared to unsafe-inline.

Background

With 'unsafe-inline' in script-src (Phase 2), CSP provides ~40% XSS protection. With nonces, it provides ~95% protection because:

  • Inline scripts without the correct nonce are blocked
  • Attacker-injected scripts don't have the nonce
  • 'strict-dynamic' allows legitimately loaded scripts to load additional scripts

Implementation

Middleware (apps/blog/middleware.ts)

  • Generates cryptographically secure nonce using crypto.randomUUID()
  • Builds CSP header with nonce in script-src and style-src
  • Uses 'strict-dynamic' for script loading chains
  • Passes nonce to app via x-nonce header

Layout (apps/blog/app/layout.tsx)

  • Reads nonce from headers
  • Passes nonce to Script components

What's Implemented

  • Nonce generation in middleware
  • CSP header with nonce
  • Nonce passed to layout
  • Script component uses nonce

What Still Needs Work

  • Wallet app implementation
  • All Script components in the app need nonce prop
  • Third-party script handling (Twitter embeds, etc.)
  • HBAuth/Beekeeper WASM testing
  • Hive Keychain compatibility testing
  • Comprehensive E2E testing
  • Switch from Report-Only to enforcing mode

Dependencies

This MR depends on:

Test Plan

Before merging:

  • Deploy to staging
  • Verify nonce in CSP header changes per request
  • Test all app functionality
  • Test all embedded content
  • Test authentication flows
  • Monitor CSP violations
  • Verify no console errors

Notes

This is marked as draft because it requires:

  1. Phase 2 (Report-Only) to be deployed and monitored first
  2. Comprehensive testing before switching to enforcing mode
  3. Possible adjustments based on Report-Only violations

Merge request reports

Loading