harden: ClusterFuzzLite fuzzing of the session-cookie auth boundary + job-scoped deploy token#29
Merged
Merged
Conversation
… job-scoped deploy token
sprayberry-reviewer
approved these changes
Jul 12, 2026
sprayberry-reviewer
left a comment
Collaborator
There was a problem hiding this comment.
Maintainer-authorized direct approval to satisfy the required-review gate. This PR (ClusterFuzzLite fuzzing of the session-cookie auth boundary + job-scoped deploy token) was authored and verified by the maintainer — CI green, worker syntax-checked, fuzz burst clean (40,801 runs, flat RSS). Recorded as a direct approval, not an automated code review.
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.
The deepdive/hands/browser-bridge Scorecard playbook applied to amnesia — closes the two code-fixable open alerts (Fuzzing #5, Token-Permissions #1).
Fuzzing — alert #5
ClusterFuzzLite + Jazzer.js over the one input an anonymous internet client fully controls on
api.amnesia.tax: the Worker's signed session cookie, which decides whether a request skips Turnstile.fuzz/session.fuzz.jspins its contracts:SESSION_SECRETpassing the HMAC gate = free, un-gated search access).buildCookieresult always verifies under its own secret, never under a different one, never after expiry.timingSafeEqual/readCookienever throw on hostile input.To make these testable the four cookie helpers (
buildCookie,verifySession,timingSafeEqual,readCookie) plusCOOKIE_NAMEare now named exports beside the Worker's default export — zero runtime change (the Workers runtime only invokes the default).cflite.ymlruns weekly (Monday 06:37 UTC, batch, 300s);npm run fuzzis the local loop. Base image digest-pinned, with a dependabotdockerentry keeping the pin fresh (and annpmentry for the jazzer devDependency).One real bug the fuzzer caught during development — in the harness, not the Worker: the target is async (WebCrypto HMAC), and Jazzer's
--syncmode fires the promises without awaiting them, so pending crypto ops flooded into an OOM (2.1GB, "762k runs in 7s" — it wasn't actually awaiting). Fixed by running in Jazzer's async mode; RSS then held flat at ~195MB and the 40k-run burst found zero assertion failures. Recorded in the build.sh/run.mjs comments so the next JS-with-WebCrypto target doesn't repeat it.Token-Permissions — alert #1
deploy.ymlhelddeployments: writeat the workflow level; it moves to the single deploy job, top level drops tocontents: read. Same steps, same effective scope. (deploy-worker.yml, canary.yml, ci.yml were already read-only.)Verified locally
src/) and Worker are untouched behaviorallyNo version bump — amnesia isn't a published package; it deploys on push to main (the site via
deploy.yml, the Worker viadeploy-worker.yml), and neither the static site nor the Worker runtime is changed by this PR.Not code-fixable, tracked separately: #2 Code-Review (0-approval solo ceiling — the reviewer bot's approvals now accrue toward it), #6 SAST (7 — pre-CodeQL commits aging out of the window; the advanced-setup workflow merged today in #28 covers new commits), #3 CII (operator enrollment). Branch-Protection isn't scored yet — no
SCORECARD_TOKENsecret on this repo; the same PAT used on the other repos surfaces it.