Repository navigation
Device login: wrong codes from one network no longer lock out its other users - #886
Merged
Merged
Conversation
…er users Wrong user codes were counted per client network with the session's budget, ten per five minutes, so one user's typos, or a page opening /device?code=… for a signed-in victim, locked every user of the network (of the install, behind an untrusted proxy) out of /device. The network now has a throttle of its own, a hundred wrong codes per five minutes; the session's stays at ten. The /device page looks a filled-in code up only once the user clicks Continue. Fixes #803 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012e6DJbn62iKFkhRepaeRCW
schmitch
enabled auto-merge
November 3, 2026 23:01
Member
Author
|
CI I merged Generated by Claude Code |
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.
Fixes #803
What changed
/devicewere counted per client network in the same throttle as the per-session ones, ten per five minutes. That meant one user's typos, or a page opening/device?code=…ten times for a signed-in victim, locked every user behind that NAT out. Withoutauth.trusted_proxy_cidrs, it locked out every user of the install. The network now has its own throttle,AppState::device_network_throttle, allowingDEVICE_CODES_PER_NETWORK= 100 wrong codes per five minutes. That is still far too few to guess a code out of 20^8. The per-session budget (device_code_throttle) stays at ten per five minutes. A 429'sRetry-Aftercomes from whichever throttle refused./device?code=…(web/src/routes/Device.tsx) now only fills the code in. The page says "Check that this is the code your terminal shows, then continue." and runs the lookup when the user clicks Continue. So a page opened by someone else spends neither the session's budget nor the network's. Approval still needs the click on Approve, as before.docs/deployment.md(Device login, Guessing and The/devicepage) states both limits and the click.Tests
crates/server/tests/device_auth.rs:wrong_codes_in_one_session_leave_the_network_its_other_sessions: two sessions from one address. Ten wrong codes in one cut that session off with 429, and the other session still looks the code up (200) and approves it (204).a_network_is_cut_off_after_a_hundred_wrong_codes: ten sessions × ten wrong codes from one address. A fresh session of that network then gets 429 withRetry-After, and another network still finds the code.guessing_a_code_is_cut_off_by_the_rate_limitnow expects the network's other session to find the code instead of being refused.origin/main), all three fail:left: 429, right: 200for the colleague's session, and 429 instead of 404 before the hundredth code. With the fix, all 13 tests in the file pass.web/src/routes/Device.test.tsx:cargo fmt --all --check,cargo clippy -p forge-server --all-targets -- -D warnings,cargo test -p forge-server --liband--test device_auth(Postgres pulled through mirror.gcr.io),pnpm run tsc,pnpm run test(622 passed),cargo xtask changelog --check.Changelog
docs/changes/2.2.0/803.fixed.mdGenerated by Claude Code