Public: anyone can read this; nobody can change it.
Every password door counts in the sign-in windows: the API session and token doors, HTTP Basic and the terminal sign-in go through one throttled verify #42
Check · Review · Land done · Live — Landed; nothing deploys from this branch, so this is the end of its path.
**Problem.** Four password doors had no sign-in limit: `POST /api/v1/sessions`, the password branch of `POST /api/v1/tokens`, HTTP Basic on any request (it gives scope `admin`), and the terminal sign-in. A client could guess passwords with no limit. Each guess also used one argon2 verify.
shipped merged
Sign in to join this conversation.
new above
offline
Problem. Four password doors had no sign-in limit:
POST /api/v1/sessions, the password branch ofPOST /api/v1/tokens, HTTP Basic on any request (it gives scopeadmin), and the terminal sign-in. A client could guess passwords with no limit. Each guess also used one argon2 verify.Root cause. The sign-in windows (#2439, #2366, #2470) were in the
/signinpage handler.verifyPasswordwas exported, so each door had to remember to ask the windows first. Four doors did not.Fix.
src/core/signin-window.ts(per account, per source, per forge, same limits and keys).signinAllowedfor the passkey, claim and parent doors calls it.verifyPasswordThrottled(db, { username, password, source })is the only exported password check. It counts the attempt before argon2. The raw check is not exported, so a new door cannot skip the windows./signin, the API session and token doors (429 withretry-after), HTTP Basic (401 when throttled, also for the right password), the terminal (throttled) and the password change.Test.
test/signin-password-doors.test.ts: withsignin.per_account= 3, three wrong tries, then the right password is refused at each door. Tries at/signinclose the API door. 9 right Basic passwords in a row all pass. No module butcore/users.tscallsBun.password.verify. On main: 6 of 7 fail. With the fix: 8 of 8 pass.test/throttle-scope.test.tsnow expects the API password sign-in to be refused by the full sign-in window.Validate (fast). Result: baseline. Only
contain.test.ts,release-handover.test.tsandweb-code.test.tsfailed, and they also fail on main 1051d451 on this box. tsc passes.