fix(netlify): Add blocking CSP header#1097
Conversation
Signed-off-by: Jonah Kowall <jkowall@kowall.net>
There was a problem hiding this comment.
Pull request overview
This PR hardens the Netlify deployment by adding a site-wide Content-Security-Policy (CSP) header and refactoring templates to avoid inline scripts so the CSP can keep script-src free of 'unsafe-inline'.
Changes:
- Add a blocking CSP header in
netlify.tomland update htmltest ignores for the new external Google CSE script URL. - Move previously-inline JavaScript (theme initialization, Mermaid initialization, banner cloning) into
static/js/*files referenced via<script src=...>. - Override the search template to load Google CSE via an external script URL.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| themes/docsy-overrides/layouts/search.html | Adds a custom search template that loads Google CSE via an external script. |
| themes/docsy-overrides/layouts/_partials/hooks/body-end.html | Replaces inline banner-clone script with a static JS file include. |
| themes/docsy-overrides/layouts/_partials/head.html | Replaces inline theme initialization script with a static JS file include. |
| themes/basetheme/layouts/shortcodes/mermaid.html | Replaces inline Mermaid initialization with a static JS file include. |
| static/js/theme-init.js | New extracted theme initialization logic used by head.html. |
| static/js/mermaid-init.js | New extracted Mermaid initialization logic used by the Mermaid shortcode. |
| static/js/banner-clone.js | New extracted banner cloning logic used by the body-end hook. |
| netlify.toml | Adds the site-wide CSP header and related security headers. |
| .htmltest.yml | Ignores the externally loaded Google CSE script URL and updates cSpell ignore list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> | ||
| <script> | ||
| var config = { | ||
| startOnLoad: true, | ||
|
|
||
| // useMaxWidth:true ensures the SVG scales with the main panel as it's resized | ||
| // and prevents the image from overlapping with menu panels. | ||
| flowchart: { useMaxWidth: true, htmlLabels: false }, | ||
|
|
||
| // See: https://github.com/mermaid-js/mermaid/issues/790#issuecomment-478860052 | ||
| // Prevents text in labels from getting cut off at the end. | ||
| themeCSS: ".label foreignObject { font-size: 90%; overflow: visible; }" | ||
| }; | ||
| mermaid.initialize(config); | ||
| </script> | ||
| <script src="{{ "js/mermaid-init.js" | relURL }}"></script> |
There was a problem hiding this comment.
Addressed in 1d593dc: pinned Mermaid to 11.15.0 and added the matching sha384 SRI hash plus crossorigin="anonymous" on the jsDelivr script tag. Verified with npm run build, npm run check:format, and git diff --check.
| @@ -0,0 +1,17 @@ | |||
| (function () { | |||
| const themeKey = 'td-color-theme'; | |||
| const storedTheme = localStorage.getItem(themeKey); | |||
There was a problem hiding this comment.
Addressed in 1d593dc: wrapped the localStorage.getItem(...) lookup in try/catch and fall back to the media-query-derived theme when storage access is unavailable. Verified with npm run build, npm run check:format, and git diff --check.
| themeCSS: '.label foreignObject { font-size: 90%; overflow: visible; }', | ||
| }; | ||
|
|
||
| mermaid.initialize(config); |
There was a problem hiding this comment.
Addressed in 1d593dc: mermaid-init.js now checks window.mermaid before initializing, so pages degrade cleanly if the CDN script is blocked or fails to load. Verified with npm run build, npm run check:format, and git diff --check.
Signed-off-by: Jonah Kowall <jkowall@kowall.net>
3c4e894 to
1d593dc
Compare
Summary
script-src 'unsafe-inline'.OpenSSF
Refs jaegertracing/jaeger#8600
Refs jaegertracing/jaeger#8484
Parent tracker: jaegertracing/jaeger#8481
Validation
npm run buildnpm run check:filenamesnpm run check:formatPATH=/Users/jkowall/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin:$PATH npm run check:spellingnpm run check:links:internal<script>blocks./,/docs/latest/,/download/, and/search/reported no CSP console violations.