Skip to content

Add per-response CSP nonces - #2363

Draft
niemyjski wants to merge 12 commits into
mainfrom
feature/strict-dynamic-csp
Draft

niemyjski wants to merge 12 commits into
mainfrom
feature/strict-dynamic-csp

Conversation

@niemyjski

@niemyjski niemyjski commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

Serve frontend HTML with a fresh 32-byte nonce and a strict script CSP, without unsafe-inline or unsafe-eval. The existing ASP.NET response pipeline stamps scripts, disables HTML caching, and prevents conditional or range requests from returning a body with a mismatched nonce. API responses and MCP streaming bypass the transformation.

Use the same tested policy in production and the development frontends. Remove the unused SPA file-reading middleware, keep Angular object rendering compatible with CSP, and configure Svelte's Zod validation to avoid runtime code generation.

Verification

  • Rebased onto main at bb0315556.
  • .NET test-project build: 0 warnings and 0 errors; 23 focused CSP tests passed, including static files, SPA fallbacks, Scalar HTML, conditional/range/HEAD requests, nonce rotation, and API/MCP bypass.
  • Svelte: npm run validate, production build, and 13 CSP tests passed.
  • Angular: production build, focused lint, and all 9 tests passed.
  • Isolated local Chromium checks: both built login pages rendered without page errors or CSP violations; nested Angular object tables rendered correctly and kept HTML-like values inert.

Shared service tests and authenticated/provider flows were not run locally. Scalar rendered, but its bundled code still reported a caught eval probe and blocked external font/registry requests; this is not a claim of complete Scalar or provider compatibility.

Breaking changes

No API route, response schema, authorization, or configuration changes. Frontend scripts now require a valid nonce or a trusted loader; inline styles remain allowed.

@niemyjski

Copy link
Copy Markdown
Member Author

Current-feedback closeout (2026-07-26):

  • Re-fetched the live head (0bddf5a) and current main (dc940dd); the PR is clean, mergeable, and zero commits behind.
  • Audited every feedback surface: 0 GraphQL review threads, 0 inline comments, 0 submitted reviews, and 0 human issue comments. The coverage-bot comment is current informational output and needs no code action.
  • Re-reviewed the complete effective diff under the thermo-nuclear maintainability bar. No additional change is justified: CSP ownership remains isolated from host wiring, Program.cs shrinks, the three runtime policies are guarded by one parity contract, no source file crosses 1,000 lines, and dev-only LiveReload transformation complexity stays confined to its middleware.
  • Local proof: SpaIndexHtmlMiddlewareTests 17/17; Svelte CSP tests 12/12; Angular CSP/renderer tests 7/7; Exceptionless.Web build succeeded with 0 warnings and 0 errors; Svelte and Angular production builds succeeded.
  • Live CI is fully green, including API, client, E2E, Docker, version, and CLA.

No follow-up commit was necessary, and draft/admin state was left unchanged.

@niemyjski niemyjski self-assigned this Jul 30, 2026
@niemyjski
niemyjski force-pushed the feature/strict-dynamic-csp branch from 0bddf5a to 7ee01eb Compare July 30, 2026 18:18
@niemyjski niemyjski changed the title Secure SPA script loading with strict CSP Add per-response CSP nonces Jul 30, 2026
@niemyjski
niemyjski force-pushed the feature/strict-dynamic-csp branch 2 times, most recently from b7eab28 to 3cb0aa3 Compare July 30, 2026 19:39
@niemyjski

Copy link
Copy Markdown
Member Author

Fixed the failing CSP fallback integration coverage in 9f10cf351 by making the integration host exercise the production response-level nonce middleware and SPA fallback delegate.

Verification after push:

  • Local test project build: 0 warnings, 0 errors
  • SpaIndexHtmlMiddlewareTests: 17/17 passed
  • CspNonceTests: 3/3 passed
  • GitHub CI: client, full API coverage suite, E2E, version, and Docker build all passed

Re-audited the review surfaces: there are no submitted reviews or review threads to resolve.

@niemyjski
niemyjski force-pushed the feature/strict-dynamic-csp branch from 8e10da9 to f8d1597 Compare September 16, 2026 00:32
@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.Insulation 37% 35% 286
Exceptionless.Web 85% 70% 8133
Exceptionless.Core 76% 68% 10538
Exceptionless.AppHost 38% 41% 147
Summary 79% (26471 / 33491) 68% (12290 / 18073) 19104

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant