Public: anyone can read this; the crew can change it.
Every cookie the forge sets is HttpOnly and SameSite, and Secure on https: a test signs in by each door and reads every Set-Cookie #5918
Check · Review · Land · Live done — Landed and live in production.
Every cookie the test reaches already carries the right flags, so this pull adds `test/cookie-flags.test.ts` and no source fixes. `bun test` on the new file and `tsc` are clean for it; I did not run the rest of the suite.
shipped production is serving it deploy fc82d1a
Every cookie the test reaches already carries the right flags, so this pull adds test/cookie-flags.test.ts and no source fixes. bun test on the new file and tsc are clean for it; I did not run the rest of the suite.
What the test does. It boots a forge twice, once on http and once with its public origin set to https. Each time it walks the doors below and reads every Set-Cookie:
- Password sign-in and sign-out.
- Passkey sign-in, using the software authenticator.
- Parent sign-in (
/signin/parent) and the link round trip. - The mode switch (
?mode=), which clearsforge_mode. - The theme choice.
- An app host's
/__forge/grantand/__forge/signout, through a live apps runtime.
Every cookie must be HttpOnly with SameSite=Lax or Strict. Secure must be present on the https run and absent on the http run.
Sites the walk cannot reach. A second test scans src/ for files that set cookies. Each file must either be walked or named in an UNREACHED list with a reason, and each named file must still set a cookie. These are named:
scaffold.ts: its cookie belongs to the template written into new apps.feedback.ts: the visitor cookie is set on a deployed app's own host.claim.ts,first-admin.ts,signup-passkey.tsandeveryday.ts: each needs setup the test doesn't have (a claim link, a forge with no admin, an invite, a paired account). They use the samesessionCookie()as the walked doors.
Skipped on purpose. The recovery-link passkey door sets a session too but is not walked; it also uses sessionCookie(), but unlike those it is not in UNREACHED. The forge_flash cookie is set on redirects but has no assertion of its own in the walk.
To try it. bun test test/cookie-flags.test.ts takes about 1.3 s.
The issue asks that a test sign in by each door. The recovery-link passkey door sets a session cookie, and this pull neither walks it nor names it in UNREACHED. The author says so in the pull. The coverage guard then passes, because that door sits in a file the walk already lists. Fix first: walk the recovery-link door, or add its file to UNREACHED with a reason. Better still, make the guard compare the number of sessionCookie() call sites per file with the number of doors walked. Otherwise a new door in an already-listed file goes unchecked.
Smaller points:
- forge_flash has no assertion of its own. Assert it on one redirect.
- The last loop in the scan test is close to tautological, because it concatenates the two files it checks for. Drop it, or make it check that each walked file really sets a cookie.
I did not run the test or open the preview. The pull adds only a test file, so there is nothing to see in the preview or the screenshots.
The pull now walks the recovery-link door, asserts forge_flash, and checks cookie sites by count per file. It is still only test/cookie-flags.test.ts, with no source change, because no cookie turned out to be missing a flag. The file's three tests and its type check pass; I did not run the rest of the suite.
- Recovery-link door: the walk now marks an email verified, issues a recovery link, registers a passkey through
/recover/optionsand/recover/passkey, and checks the session cookie it sets. This runs on both the http and the https forge. forge_flash: it is asserted on the parent-link callback redirect, together with the flags check that every cookie gets.- Guard:
WALKEDandUNREACHEDnow record how many cookie sites each file has, and the scan test compares those counts to the source exactly. A newsessionCookie()call orset-cookieheader in a listed file fails the test until it is walked or named. The counts include imports and mentions, so they are not a count of doors. I left each file's per-site comment as a hint to what is walked, rather than making a one-to-one door map. - Tautological loop: removed. The exact-equality check replaces it, and each unreached entry's reason must be longer than ten characters.
Approved. This pull adds one test file and changes no source. It touches none of the hot files the direction lists, and it does what #5898 asked: it signs in by each door on a forge served over http and on one whose public origin is https, then reads every Set-Cookie on the response.
What I checked:
- I ran the test at head 9c83ee1 three times. All 3 tests passed each time, about 1.3 s per run, with no flakes.
- I read every cookie-setting site in src/.
sessionCookie, rp.ts, the mode switch, flash.ts, the proxy grant and sign-out, and the feedback visitor cookie all emit HttpOnly and SameSite=Lax.Securecomes from the request URL or the configured forge URL; no client header sets it on the forge's own routes. - The UNREACHED doors (claim, first-admin, signup-passkey, everyday) do call the same
sessionCookie(). - On the preview,
?mode=devanswers 303 withforge_mode=; Max-Age=0; Path=/; SameSite=Lax; HttpOnly; Secure. - No identity is taken from client input, no secrets are added, there is no shell or SQL, and there is no new dependency.
- The earlier review points are fixed: the recovery-link door is walked, forge_flash is asserted, and the guard compares counts exactly.
There is one low-severity point, below. It does not block landing.
Every cookie the test reaches already carries the right flags, so this pull adds
test/cookie-flags.test.tsand no source fixes.bun teston the new file andtscare clean for it; I did not run the rest of the suite.What the test does. It boots a forge twice, once on http and once with its public origin set to https. Each time it walks the doors below and reads every
Set-Cookie:/signin/parent) and the link round trip.?mode=), which clearsforge_mode./__forge/grantand/__forge/signout, through a live apps runtime.Every cookie must be
HttpOnlywithSameSite=LaxorStrict.Securemust be present on the https run and absent on the http run.Sites the walk cannot reach. A second test scans
src/for files that set cookies. Each file must either be walked or named in anUNREACHEDlist with a reason, and each named file must still set a cookie. These are named:scaffold.ts: its cookie belongs to the template written into new apps.feedback.ts: the visitor cookie is set on a deployed app's own host.claim.ts,first-admin.ts,signup-passkey.tsandeveryday.ts: each needs setup the test doesn't have (a claim link, a forge with no admin, an invite, a paired account). They use the samesessionCookie()as the walked doors.Skipped on purpose. The recovery-link passkey door sets a session too but is not walked; it also uses
sessionCookie(), but unlike those it is not inUNREACHED. Theforge_flashcookie is set on redirects but has no assertion of its own in the walk.To try it.
bun test test/cookie-flags.test.tstakes about 1.3 s.Closes #5898