Skip to content

Harden generated worker and site config - #188

Merged
shigahi merged 2 commits into
masterfrom
harden-worker-and-site
Oct 28, 2026
Merged

shigahi merged 2 commits into
masterfrom
harden-worker-and-site

Conversation

@shigahi

@shigahi shigahi commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes from a review against the Cloudflare Workers best practices.

Generated worker (src/code.ts)

  • Remove the permissive CORS handling. The worker answered cross-origin preflights and /api/* responses with Access-Control-Allow-Origin: *. The Notion client calls the custom domain from the same origin, and notion.site itself sends no CORS headers to other origins, so this only let third-party pages call the proxied API from a browser. OPTIONS now returns just an Allow header.
  • fetchJs drops the query string from the edge cache key and the upstream fetch. Chunk URLs are content-hashed, and before this change any random query (/_assets/x.js?1) bypassed the cache and forced a new fetch and rewrite.
  • Foreign page checks are also stored in caches.default (1 day, keyed by CACHE_VERSION), so a new isolate doesn't send another getPublicPageData request before serving an unmapped page. Failed checks are still served and never cached, as before.

Site (wrangler.jsonc, public/)

  • not_found_handling is now 404-page, with a new public/404.html. The site isn't a single-page app, so the SPA setting returned the landing page with status 200 for any unknown path (soft 404).
  • Add public/_headers with X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy and Permissions-Policy. Production currently sends none of them.
  • Update compatibility_date to 2026-10-28. The Worker is assets-only, so this has no runtime effect.

Not changed: I also considered adding frame-ancestors to the generated worker, because it deletes Notion's CSP. It isn't needed: Notion's HTML responses carry X-Frame-Options: SAMEORIGIN, and the worker passes that through (checked on sensitive-information.classmethod.live).

Verification

  • npm test: 12 tests pass. Four tests are new, and forward() now also asserts that there is no CORS header. Against the old src/code.ts, the three new behavior tests and the eight API tests fail. The fourth new test (failed checks are not cached) passes on both versions; it guards against regressions.
  • npm run check:render against live Notion: no FAIL. Four checks are NOTION, meaning they fail on notion.site too: database views, database rows, database item, and navigation.
  • npm run build, then wrangler dev on the site:
    • / and /ja/ return 200.
    • /ja redirects to /ja/.
    • /this-does-not-exist and /ja/nope return 404 with the new page.
    • The headers from _headers are present.

After merge

  • Deploy the site to apply the 404 handling and headers.
  • Changes to the generated worker only reach existing sites when users regenerate and redeploy their script.

shigahi and others added 2 commits October 28, 2026 11:18
The worker answered cross-origin preflights and API responses with
Access-Control-Allow-Origin: *, although the Notion client only calls
the domain from the same origin and notion.site sends no CORS headers.

JS chunk requests now drop the query string from the cache key and the
upstream fetch, so a random query can no longer bypass the cache and
force a new rewrite. Foreign page checks are also kept in the edge
cache, so new isolates don't ask Notion again; failed checks are still
not cached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The site is not a single-page app, so the SPA not-found handling served
the landing page with status 200 for any path. Serve a 404 page instead,
add baseline security headers via _headers, and update the
compatibility date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shigahi
shigahi merged commit f5cf4ad into master Oct 28, 2026
5 checks passed
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