fix(auth)!: a session alone never gets a code checked
The third reading found a stolen session guessing TOTP codes without end: nine wrong codes for new recovery codes, then removing an unconfirmed authenticator of its own, a success that cleared the session's count. As Proton has it, every signed-in change of how an account is secured now takes the owner's proof (OwnerProof): the password's SRP proof for a change's challenge and a TOTP or recovery code. Adding an authenticator once one is confirmed, removing a confirmed one, new recovery codes, a new phrase, a new password and deleting take it; only the first authenticator is confirmed with its own code alone, and removing an unconfirmed one takes nothing. A proof given where none is taken is refused, and a confirmed authenticator's code is never checked for a session alone, so no success passes a proof unchecked. A session's proofs count for it alone, before they are checked, cleared only by one accepted; the tenth wrong in a row ends the session. They never count toward the account's waits nor wait for them, so whoever knows the password no longer holds a signed-in owner out of changing it (the second finding), and a new password forgets those waits. Beginning a change counts nothing against the account (the third finding): 30 an hour per session, holding back that session alone. Deleting takes a TOTP code wherever an authenticator is confirmed, a code by mail where no second factor works (the fourth finding), which SignInWays now tells (secondFactorWorks). Signed-in calls no longer take the address: nothing there mails. wrongExistingCode goes, a wrong existing code being a wrong proof. The app follows in the next commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
70b434bb84
commit
a9459bb875
1 changed files with 1461 additions and 1026 deletions
|
|
@ -194,15 +194,15 @@ abstract interface class AccountRegister {
|
|||
required String label,
|
||||
});
|
||||
|
||||
/// Confirms [person]'s [authenticator], with [existingCode] from one
|
||||
/// confirmed before where the account has one; the first one's recovery
|
||||
/// codes. Refusals as `confirmAuthenticator`'s.
|
||||
/// Confirms [person]'s [authenticator], with the owner's [proof] where
|
||||
/// the account has one confirmed already; the first one's recovery codes.
|
||||
/// Refusals as `confirmAuthenticator`'s.
|
||||
Future<List<String>> confirmAuthenticator(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required UuidValue authenticator,
|
||||
required String code,
|
||||
String? existingCode,
|
||||
OwnerProof? proof,
|
||||
});
|
||||
|
||||
/// [person]'s authenticators, the oldest first.
|
||||
|
|
@ -217,14 +217,15 @@ abstract interface class AccountRegister {
|
|||
Session session, {
|
||||
required UuidValue person,
|
||||
required UuidValue authenticator,
|
||||
String? code,
|
||||
OwnerProof? proof,
|
||||
});
|
||||
|
||||
/// New recovery codes for [person]. Refusals as `newRecoveryCodes`'.
|
||||
/// New recovery codes for [person], with the owner's [proof]. Refusals as
|
||||
/// `newRecoveryCodes`'.
|
||||
Future<List<String>> newRecoveryCodes(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required String code,
|
||||
required OwnerProof proof,
|
||||
});
|
||||
|
||||
/// Asks for the reset of a lost authenticator. Refusals as
|
||||
|
|
@ -299,34 +300,20 @@ abstract interface class AccountRegister {
|
|||
Future<void> changePassword(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required UuidValue challenge,
|
||||
required ByteData clientValue,
|
||||
required ByteData clientProof,
|
||||
String? totpCode,
|
||||
String? recoveryCode,
|
||||
required OwnerProof proof,
|
||||
required NewPassword password,
|
||||
UuidValue? keepSession,
|
||||
required String host,
|
||||
required String address,
|
||||
required String language,
|
||||
});
|
||||
|
||||
/// Replaces the wrapping of [person]'s keys under their recovery phrase
|
||||
/// and the phrase's proof key, with the password's proof and a code.
|
||||
/// Refusals as `setRecoveryKeys`'.
|
||||
/// and the phrase's proof key, with the owner's [proof]. Refusals as
|
||||
/// `setRecoveryKeys`'.
|
||||
Future<void> setRecoveryKeys(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required UuidValue challenge,
|
||||
required ByteData clientValue,
|
||||
required ByteData clientProof,
|
||||
String? totpCode,
|
||||
String? recoveryCode,
|
||||
required OwnerProof proof,
|
||||
required WrappedKeys recoveryKeys,
|
||||
required ByteData recoveryProofKey,
|
||||
required String host,
|
||||
required String address,
|
||||
required String language,
|
||||
});
|
||||
|
||||
/// Deletes the account [person] with everything the register's server has
|
||||
|
|
|
|||
Loading…
Reference in a new issue