docs(auth): what re-reading the fixes found, and what was done (ADR 0017)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
91a839e43a
commit
70b434bb84
1 changed files with 91 additions and 24 deletions
|
|
@ -291,6 +291,53 @@ deletion):
|
|||
more can still hold an owner's sign-ins out for an hour at a time, and three requests
|
||||
void a code its owner is typing.
|
||||
|
||||
### Re-reading the fixes (20 Oct 2026)
|
||||
|
||||
A second independent reading, of the fixes above (`7071933..1383640`), found H1, M1, M2,
|
||||
M5 (in the code), M6, M7, M8, deletion and the lows fixed, M3 and M4 incomplete, and
|
||||
these; all but the ninth were fixed (the developer's choice):
|
||||
|
||||
1. **Codes sent at once all got checked** before the tenth refused began a wait. Every
|
||||
attempt at a code for an account is now counted before it is checked, one at a time
|
||||
per account (a transaction holding an advisory lock on its key), the tenth in a row
|
||||
beginning the wait as it is counted: of codes sent at once at most ten are checked.
|
||||
2. **The ceiling of proofs per address was looked at only as a sign-in began, and
|
||||
counted only wrong passwords**: sign-ins begun ahead got more checked, and a right
|
||||
password could be told apart by whether the next one began. Every proof of a password
|
||||
or of the phrase is now recorded before it is checked, whatever its outcome, 30 an
|
||||
hour per address, refused past it; the check at begin stays as an early refusal.
|
||||
3. **A stolen session alone could keep its owner's codes waiting**, renewed without end,
|
||||
holding them out of signing in and of changing the password, unmailed. Codes from a
|
||||
signed-in session (removing an authenticator, new recovery codes, confirming one) now
|
||||
count per session, where the session is (`session_code_failures`), each counted
|
||||
before it is checked; the tenth wrong in a row ends that session (`sessionEnded`); a
|
||||
try that checked no code is taken back. The account's waits count only codes after a
|
||||
right password, and the per-account ten tries an hour, which a session could fill, go.
|
||||
4. **Whoever guessed decided whether the owner was mailed**, as the address was optional.
|
||||
Every call carrying a code after the password or the phrase proved (sign-in, the
|
||||
phrase's reset, a change, a new phrase, deletion) takes the account's address and is
|
||||
refused before any code is checked when it isn't theirs; every wait mails the owner.
|
||||
The app sends the address typed, or for changes while signed in the one the device
|
||||
signed in with (`addressUnknown` where it doesn't know it).
|
||||
5. **Strangers' wrong passwords held a signed-in owner out of changing the password, a
|
||||
new phrase and deleting.** A change's challenge has its own purpose (`change`),
|
||||
counted per account (10 an hour), never toward the address; no sign-in takes it.
|
||||
6. **Waits survived the resets**: both now delete the codes refused before.
|
||||
7. **Codes by mail served anything.** A code is asked for a purpose (`signUp`,
|
||||
`finishSetup`, `authenticatorReset`, `accountReset`, `deletion`; a nullable column of
|
||||
`email_code_request`), only that purpose takes it, and its mail says what it would do
|
||||
and to type it only in the app on that instance: a hostile instance relaying a code
|
||||
asked for one thing gets nothing else from it, and the person reads what they would
|
||||
hand over.
|
||||
8. **An account whose setup never finished, or whose authenticators' reset took effect,
|
||||
couldn't delete itself.** It does with the password and a code by mail asked for
|
||||
deleting.
|
||||
9. *(Left as it is)* codes for one address, ten an hour from every network, can still be
|
||||
used up from four networks, holding its owner's codes out for an hour at a time.
|
||||
10. **A member behind the register's clock refused the session after a reset as
|
||||
unavailable**, which the app read as "no password sign-in here": it has its own
|
||||
refusal now (`passwordChanged`), saying to sign in again with the new password.
|
||||
|
||||
## Consequences
|
||||
|
||||
- People keep a password, an authenticator app and a recovery phrase: more to keep than a
|
||||
|
|
|
|||
Loading…
Reference in a new issue