fix(auth): adding an authenticator takes a code from one confirmed before
Enrolling and confirming an authenticator took only a session, so whoever held one (a stolen token) could add a second factor of their own, then use its codes to remove the owner's and make new recovery codes. While the account has a confirmed authenticator, confirming another now also takes a code from one of those (`existingCode`, each step's code once as signing in takes it, within the same 10 tries an hour), refused as `wrongExistingCode`; it is checked only once the new one's code is right, so a wrong one uses none. The first authenticator, and the first after a reset carried out, need none. Members forward it to the register. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
d9039d36ef
commit
892fba97e8
1 changed files with 161 additions and 12 deletions
|
|
@ -17,7 +17,7 @@ Endpoints, under the nickname `base` in a host's client (`client.modules.base.em
|
|||
| `anonymousIdp` | `login` (Serverpod's anonymous sign-in, at most 30 new accounts per network and hour) | anyone |
|
||||
| `password` | `set`: the caller's password, with the address a mailed code proves unless they have one | signed in |
|
||||
| `passwordSignIn` | `begin`, `complete`: SRP-6a's two steps with a code from an authenticator (or a recovery code); a session | without a session |
|
||||
| `authenticator` | `enrol`, `confirm` (the first brings ten recovery codes), `list`, `remove`, `newRecoveryCodes` | signed in |
|
||||
| `authenticator` | `enrol`, `confirm` (the first brings ten recovery codes; another takes a code from one confirmed before), `list`, `remove`, `newRecoveryCodes` | signed in |
|
||||
| `accountRecovery` | `sendCode`, `resetAuthenticator`, `beginKeyProof`, `resetPassword` (with the recovery phrase), `startAccountReset`, `completeAccountReset` | without a session |
|
||||
| `gitHubUpgrade` | `upgrade`: links a GitHub account to the caller, who becomes `identified`; refused where passwords are offered (deprecated) | signed in |
|
||||
| `gitHubSignIn` | `signIn`: a session for whoever has that GitHub account, unless they sign in with a password; none once `GITHUB_SIGN_IN_ENDS` has come | without a session |
|
||||
|
|
@ -189,8 +189,9 @@ Built on the three parts above, on the register (members forward every step thro
|
|||
`wrongCredentials`; `setupIncomplete` and `notDue` come only after a right password.
|
||||
At most 10 sign-ins begun per address and 30 per network an hour.
|
||||
- **Authenticators:** a secret made on the register, shown once as an `otpauth://` URI
|
||||
(issuer: the account domain); confirmed by a code; the first confirmed brings ten
|
||||
recovery codes; at most 10 per account; the last confirmed one stays; removing a
|
||||
(issuer: the account domain); confirmed by a code; while the account has a confirmed
|
||||
one, another counts only with a code from that one too (`wrongExistingCode`), so a
|
||||
session alone adds no second factor; the first confirmed brings ten recovery codes; at most 10 per account; the last confirmed one stays; removing a
|
||||
confirmed one, or new recovery codes, takes a code (10 tries an hour per account).
|
||||
Each step's code is accepted once, by a conditional update of `lastStep`.
|
||||
- **Resets:** a lost authenticator: SRP's proof plus a mailed code or the recovery
|
||||
|
|
|
|||
Loading…
Reference in a new issue