Content rendering, pipeline and site hardening - #1643
Merged
Conversation
marked output now passes through a sanitize-html allowlist that keeps the renderer's own markup (fence wrappers, heading anchors, callouts) and drops everything else; link and image targets are limited to http(s), mailto and site-relative URLs; headings render inline markup through the escaping renderer. Structured-data blocks serialize through a helper that escapes < > & so a title cannot end the script tag. gray-matter's js and coffee engines are disabled. The RSS generator escapes CDATA, uses dc:creator, and absolutizes root-relative links. A content-safety test fails CI on raw scripts, frames, handlers, redirect links or code front matter in content/.
Feed titles are tag-stripped and keep angle brackets encoded, only http(s) links are kept, and the digest job builds and link-checks before opening its PR (a GITHUB_TOKEN PR never triggers the PR workflows). Read-only permissions on the PR-triggered workflows, frozen lockfile and no scripts on the write-permission ones, audit gate raised to high with overrides for js-yaml, postcss, undici and browserslist. next-pwa removed: the Turbopack build never emitted a service worker and the package pulled in a serialize-javascript advisory.
List pages hand client components a summary without the post or guide bodies, news and advent pages render markdown on the server, the PWA installer and offline page go with the removed service worker, HTML pages no longer get a one-hour browser cache, the CSP gains base-uri, form-action and object-src plus Referrer- and Permissions-Policy, the sitemap adds tag, expert and interview tier pages, /roadmaps/* redirects to /roadmap/*, and a few client lookups and parses are guarded.
Deploying devops-daily with
|
| Latest commit: |
e8276b1
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://85c10bb7.devops-daily.pages.dev |
| Branch Preview URL: | https://fix-content-rendering-harden.devops-daily.pages.dev |
…e old worker All gray-matter callers (tests, scripts, loaders) use one wrapper with the code engines disabled, so a ---js file cannot run during test collection either. A transitional /sw.js clears the old caches and unregisters itself for browsers that still hold the previous worker. The sanitizer keeps attribute case so SVG viewBox survives, storage reads check the parsed shape, and the roadmap index links to the canonical paths.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One PR for the site review, commits split by area.
Content rendering. Rendered markdown passes through a sanitize-html allowlist that keeps the renderer's own markup (fence wrappers, heading anchors, callouts) and drops raw scripts, handlers, frames,
<base>,<meta>,<form>,<style>. Link and image targets are limited to http(s), mailto and site-relative URLs. Headings render inline markup through the escaping renderer. Structured-data blocks serialize through a helper that escapes< > &. gray-matter's code engines are disabled. The RSS feed escapes CDATA, usesdc:creator, and absolutizes root-relative links. A new content-safety test fails CI on raw scripts, frames, handlers, redirect links or code front matter undercontent/.Digest pipeline and CI. Feed titles are tag-stripped with angle brackets kept encoded, only http(s) links survive, and the digest job runs the build and link check before opening its PR. PR-triggered workflows get
permissions: contents: read; write-permission workflows install with a frozen lockfile and no scripts; the audit gate ishighwith pnpm overrides for js-yaml, postcss, undici and browserslist.Dead PWA.
@ducanh2912/next-pwais a webpack plugin and the Turbopack build never produced a service worker (/sw.jsis 404 in production); the package, wrapper, installer component, offline page and header entries are removed.Payload and performance.
/posts,/guides, category, tag and expert pages pass a summary (no bodies) to their client list components instead of the full markdown. News and advent pages render markdown on the server, so highlight.js and marked leave the client bundle for those routes.Headers, SEO, small fixes. HTML routes lose the one-hour browser cache (stale HTML referenced chunk hashes that vanish on deploy). CSP adds
object-src 'none'; base-uri 'self'; form-action 'self' https://smtpfa.st, plus Referrer-Policy and Permissions-Policy. Sitemap adds tag, expert and interview-tier pages;/roadmaps/*redirects to/roadmap/*with matching canonicals. Guarded localStorage parses,Object.hasOwnlookups, a safer 404 link, and a stricter GitHub fence slug.Not in this PR (noted for later): tightening
script-srcto an allowlist needs a Carbon test; giscusstrictwas left at 0 because switching would orphan existing discussions; the remaining list pages (comparisons, interview questions, checklists, advent, exercises) can get the same summary treatment.