Skip to content

fix(csp): drop script-src unsafe-inline, tighten CDN, disable Vite polyfill - #107

Open
DavidHLP wants to merge 4 commits into
mainfrom
fix/csp-unsafe-inline-rollback
Open

fix(csp): drop script-src unsafe-inline, tighten CDN, disable Vite polyfill#107
DavidHLP wants to merge 4 commits into
mainfrom
fix/csp-unsafe-inline-rollback

Conversation

@DavidHLP

@DavidHLP DavidHLP commented Jul 5, 2026

Copy link
Copy Markdown
Owner
  • script-src back to 'self' (project ships zero author-written inline scripts)
  • jsdelivr narrowed to /npm/@fontsource/ (actual font source per shared/theme/src/typography.css:42-45)
  • cdnjs added (console/index.html:17,21 loads highlight.js + KaTeX — thana's CSP omitted these, breaking code highlighting + math rendering under CSP)
  • Vite modulePreload.polyfill=false (the only inline script Vite injects at build time)

Verified: nginx -t passes via the official template mechanism; envsubst renders connect-src with the injected API_ORIGIN.

Closes #101

DavidHLP added 2 commits July 5, 2026 11:40
- script-src 'self' (was 'self' 'unsafe-inline') — the project ships zero
  inline scripts (index.html uses only external src= for theme-bootstrap.js
  + main.ts; PWA uses registerSW external module per console/src/pwa-register.ts).
  unsafe-inline neutralized CSP's XSS defense for no benefit (HIGH 4).
- style-src: narrow https://cdn.jsdelivr.net to /npm/@fontsource/
  (actual font source per shared/theme/src/typography.css:42-45)
- style-src: add https://cdnjs.cloudflare.com/ajax/libs/highlight.js + /KaTeX/
  (console/index.html:17,21 loads these — thana's CSP omitted cdnjs, which
  would block code-highlighting + math rendering under CSP)
- font-src: narrow https://cdn.jsdelivr.net to /npm/@fontsource/
- style-src keeps 'unsafe-inline' (Vue scoped style + Tailwind v4 runtime
  injection require it; industry consensus for style is acceptable)

Verified: nginx -t passes via official template mechanism on both console
+ management; envsubst correctly renders connect-src with injected
API_ORIGIN (confirms CR HIGH 7 was correctly invalidated).

Fixes #101
…t-free

Vite's default build.modulePreload.polyfill=true injects a small inline
<script type="module"> into the built index.html. That is the only inline
script in the entire production bundle (all author code is external:
index.html uses src= for theme-bootstrap.js + main.ts; PWA uses the
external registerSW module). With the prior commit's CSP script-src
'self', the polyfill would be blocked — harmless on modern browsers
(which support <link rel=modulepreload> natively) but it produces CSP
violation noise in the browser console and undermines the "zero inline
scripts" claim at the build-output level.

Disable the polyfill. UltiCode already targets only modern browsers
(Vite 8 / Vue 3.5 / Tailwind v4 / Monaco all require ES2020+), so the
polyfill serves no real audience.

Combined with df5fe20, the production bundle now has zero inline
scripts and CSP `script-src 'self'` applies cleanly.

Refs #101

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a0e8b009f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread console/nginx.conf Outdated

# Security headers (server-level — inherited by all locations)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https:; font-src 'self' https://cdn.jsdelivr.net data:; connect-src 'self' ${API_ORIGIN}; frame-ancestors 'self'" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/npm/@fontsource/ https://cdnjs.cloudflare.com/ajax/libs/highlight.js/ https://cdnjs.cloudflare.com/ajax/libs/KaTeX/; img-src 'self' data: https:; font-src 'self' https://cdn.jsdelivr.net/npm/@fontsource/ data:; connect-src 'self' ${API_ORIGIN}; frame-ancestors 'self'" always;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow cdnjs fonts for KaTeX

For the console page, console/index.html loads KaTeX CSS from https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css, and that stylesheet references its font files under the same cdnjs KaTeX path. This CSP now allows the stylesheet in style-src, but font-src still only allows self, jsdelivr, and data URLs, so browsers will reject those KaTeX font requests under CSP and math rendering can remain degraded in production. Add the cdnjs KaTeX font path to font-src as well, or stop loading the external KaTeX stylesheet.

Useful? React with 👍 / 👎.

DavidHLP added 2 commits July 5, 2026 12:39
console's `pnpm audit --prod --audit-level high` failed on this PR's CI:
markdown-it > linkify-it <=5.0.0 has a high-severity ReDoS in the
LinkifyIt#match scan (quadratic complexity). Patched in linkify-it >=5.0.1.

markdown-it ^14.1.1's linkify-it range already allows 5.0.1, but the
lockfile was pinned at 5.0.0. Add an explicit pnpm.overrides entry —
matching the existing pattern (dompurify, lodash-es, protocol-buffers-schema,
vite, form-data) — to force ^5.0.1 across the dependency tree.

Pre-existing on main; exposed here only because this PR touches console/
files and is the first of the 5 fix branches to trigger the console audit
job (the others don't modify console/).

Verified locally: pnpm audit --prod --audit-level high → 0 high (was 1),
10 remaining (4 low + 6 moderate, below threshold). Lockfile diff minimal
(linkify-it + its direct dependents only, +11/-9).

Refs #101
Follow-up to df5fe20 (caught on self-review of all PRs).

console/index.html:21 loads katex.min.css from cdnjs.cloudflare.com. That
stylesheet declares @font-face with relative url() — e.g.
url(fonts/KaTeX_AMS-Regular.woff2) — so browsers fetch KaTeX math fonts
from https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/fonts/. The prior
font-src ('self' + jsdelivr/npm/@fontsource/ + data:) would have blocked
these, making math glyphs fall back to system fonts.

Add the precise cdnjs KaTeX prefix. management/ intentionally keeps the
narrower font-src: its index.html has no cdnjs <link> and no KaTeX-from-CDN
dependency (least privilege).

highlight.js github-dark CSS verified to contain no url()/@font-face (pure
color rules), so no cdnjs/highlight.js entry is needed in font-src.

Refs #101
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.

fix: CSP script-src 回退 unsafe-inline + jsdelivr 精确化 + 补 cdnjs

1 participant