Skip to content

Content rendering, pipeline and site hardening - #1643

Merged
bobbyonmagic merged 5 commits into
mainfrom
fix/content-rendering-hardening
Sep 2, 2026
Merged

Content rendering, pipeline and site hardening#1643
bobbyonmagic merged 5 commits into
mainfrom
fix/content-rendering-hardening

Conversation

@bobbyonmagic

Copy link
Copy Markdown
Collaborator

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, uses dc:creator, and absolutizes root-relative links. A new content-safety test fails CI on raw scripts, frames, handlers, redirect links or code front matter under content/.

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 is high with pnpm overrides for js-yaml, postcss, undici and browserslist.

Dead PWA. @ducanh2912/next-pwa is a webpack plugin and the Turbopack build never produced a service worker (/sw.js is 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.hasOwn lookups, a safer 404 link, and a stricter GitHub fence slug.

Not in this PR (noted for later): tightening script-src to an allowlist needs a Carbon test; giscus strict was 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.

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.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 2, 2026

Copy link
Copy Markdown

Deploying devops-daily with  Cloudflare Pages  Cloudflare Pages

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

View logs

…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.
@bobbyonmagic
bobbyonmagic merged commit 63aa13c into main Sep 2, 2026
4 checks passed
@bobbyonmagic
bobbyonmagic deleted the fix/content-rendering-hardening branch September 2, 2026 10:00
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