Skip to content

Comments

fix(csp): eliminate inline scripts to fix Safari CSP violations#95

Open
penso wants to merge 1 commit intomainfrom
unsafe-inline
Open

fix(csp): eliminate inline scripts to fix Safari CSP violations#95
penso wants to merge 1 commit intomainfrom
unsafe-inline

Conversation

@penso
Copy link
Collaborator

@penso penso commented Feb 12, 2026

Summary

  • Move all executable inline <script> tags to external files or non-executable types
  • Only the import map remains inline with a CSP nonce (required by spec)
  • CSP policy unchanged: script-src 'self' 'nonce-{uuid}' — no unsafe-inline added
  • Fixes Safari false-positive CSP violation reports on all 6 inline scripts

Changes

Before (inline + nonce) After
Theme init IIFE External js/theme-init.js (no nonce, allowed by 'self')
window.__MOLTIS__ = {...} <script type="application/json" id="__MOLTIS_GON__"> (non-executable, no CSP check)
Favicon emoji inline Deleted (handled by app.jsapplyIdentityFavicon())
Import map Unchanged — inline with nonce (only remaining nonce)
Title update inline Deleted (handled by app.jsapplyIdentity())
app.js module (external) Removed nonce (external scripts allowed by 'self')

Applied same pattern to login.html and onboarding.html.

Validation

Completed

  • cargo test — all 345 gateway tests pass, full suite green
  • just format-check — clean
  • cargo clippy -p moltis-gateway -- -D warnings — clean
  • biome check --write — JS files formatted

Remaining

  • Manual QA: open in Safari, verify 0 (or 1) CSP errors in Web Inspector
  • Manual QA: verify no FOUC on page load (theme-init.js loads early)
  • Manual QA: verify gon data loads (identity shown in header, models load)
  • Manual QA: verify login page branding (title, favicon)
  • E2E tests (npx playwright test)

Manual QA

Pending — requires running the gateway and checking Safari Web Inspector for CSP violation logs.

Move executable inline scripts to external files or non-executable
types. Only the import map remains inline with a CSP nonce.

- Extract theme-init IIFE to external js/theme-init.js
- Convert gon data from window.__MOLTIS__ assignment to
  type="application/json" blob parsed by gon.js
- Remove inline favicon and title-update scripts (already handled
  by app.js applyIdentity / applyIdentityFavicon)
- Remove nonce from external module scripts (allowed by 'self')
- Add applyIdentityFavicon to login-app.js
- Add theme-init.js to service worker cache

CSP policy unchanged: script-src 'self' 'nonce-{uuid}'
@codspeed-hq
Copy link
Contributor

codspeed-hq bot commented Feb 12, 2026

Merging this PR will not alter performance

✅ 34 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing unsafe-inline (6253810) with main (7fdb040)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

@codecov
Copy link

codecov bot commented Feb 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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