Cosa porta con sé quando lascia un provider di autenticazione
Cambiare provider di accesso non richiede reset delle password se l'esportazione contiene gli hash. Cosa deve contenere, e cosa importa EAuth.
Il momento in cui scopre quanto vale un provider di accesso è il giorno in cui vuole lasciarlo. Se l'esportazione contiene gli hash delle password dei Suoi utenti, li trasferisce e nessuno se ne accorge. Se non li contiene, ognuno dei Suoi utenti riceve un'e-mail «imposti una nuova password» da un'azienda di cui non ha mai sentito parlare, e una parte di loro non torna più. Questo articolo parla del primo tipo di esportazione, perché è quello che offre EAuth, e di cosa cercare prima di registrarsi da qualsiasi parte.
Perché l'hash basta
Un hash della password non è la password. È il risultato di una funzione lenta e con salt che il provider salva al posto della password, e si può usare in un solo modo: per verificare una password candidata. Consegnarlo al provider successivo gli dà esattamente ciò che aveva quello vecchio, niente di più, e il nuovo provider ci verifica le password allo stesso modo. La password dell'utente non viaggia mai, e nessuno la viene a sapere.
Per questo un provider non ha alcun motivo di sicurezza per trattenere gli hash. Ne ha uno commerciale.
Cosa deve contenere l'esportazione
Chieda un file con, per ogni account, l'indirizzo e-mail, se è stato confermato, il nome visualizzato e l'hash della password in una forma di stringa standard che dice quale funzione l'ha prodotto. Argon2id nel formato di stringa PHC ha questo aspetto: $argon2id$v=19$m=65536,t=3,p=2$...; bcrypt comincia con $2a$, $2b$ o $2y$; scrypt e PBKDF2-SHA256 hanno forme proprie, come $scrypt$ e pbkdf2_sha256$ di Django. Un hash senza i suoi parametri è inutile, quindi la forma conta quanto i byte.
Sapere se l'indirizzo era confermato conta più di quanto sembri. Un provider che riceve un account marcato come non confermato non dovrebbe semplicemente fidarsi, ed EAuth non lo fa: ne parliamo più sotto.
Le serve anche il resto dell'account: a quali organizzazioni appartiene una persona e con quale ruolo, gli inviti aperti, quali account accedono tramite il provider di identità di un'azienda invece che con una password, e i consensi che ogni persona ha dato alla Sua applicazione. I secondi fattori sono l'eccezione, e vale la pena sapere perché prima di chiederli: una passkey è legata per progetto al dominio del provider e non funzionerebbe da nessun'altra parte, e un segreto TOTP è meglio registrarlo di nuovo che copiarlo da un database all'altro. Dopo una migrazione gli utenti registrano di nuovo il loro secondo fattore, ovunque vadano.
Cosa esporta EAuth
Nella console, il proprietario e gli admin di un'applicazione trovano Export everything nella sua pagina Users. Il pulsante scarica l'applicazione come un unico file JSON: impostazioni, team, webhook, organizzazioni con membri, ruoli, inviti aperti e collegamento single sign-on, i consensi e ogni account con il suo hash della password così come è salvato. Nessun segreto viaggia con il file: né il client secret, né i secret di firma dei webhook, né le chiavi private dei collegamenti single sign-on. Quelle sono credenziali del nostro servizio, non dati Suoi.
L'hash è Argon2id in formato PHC per chi ha già effettuato l'accesso da noi, oppure l'hash con cui è stato importato chi non l'ha ancora fatto. Ogni account dice anche se il suo indirizzo è confermato, se ha un secondo fattore, quante passkey ha e, per gli account single sign-on, tramite quale provider di identità accede. È l'elenco delle persone a cui chiedere di registrare di nuovo il secondo fattore, pronto prima del trasloco. Le condizioni dicono l'essenziale in una frase, la 7.3: gli hash sono nell'esportazione nella loro forma originale, così Lei può migrare a un altro provider senza costringere i Suoi utenti a reimpostare la password. Per noi poter andarsene è una funzione, non un rischio.
L'esportazione di una singola persona, per una richiesta ai sensi dell'art. 15 o 20 GDPR, sta nella pagina di quella persona nella console, e non contiene credenziali: ciò che si sa della persona, non ciò che permette a qualcuno di accedere al suo posto.
Cosa importa EAuth
L'altra direzione passa dalla stessa porta. L'importazione accetta un array JSON o un CSV con email, password_hash e, facoltativi, display_name e email_verified, fino a 100'000 account e 25 MB per file, e riconosce Argon2id, bcrypt, scrypt e PBKDF2-SHA256 dalla forma dell'hash, quindi non serve una colonna che dica quale sia. La console prima controlla l'intero file e mostra cosa ha trovato, quanti account e in quali formati; nulla viene scritto finché Lei non conferma. Un file con una riga sbagliata viene rifiutato per intero, con la riga e il motivo, e lo stesso vale per una riga il cui indirizzo ha già un account presso la Sua applicazione, perché una base utenti importata a metà è peggio di nessuna.
Gli account importati accedono con la loro vecchia password dal momento in cui l'importazione termina. A quel primo accesso la password viene ricalcolata con Argon2id, quindi una base utenti che arriva su bcrypt si lascia bcrypt alle spalle una persona alla volta, senza che a nessuno venga chiesto di fare nulla. La console segnala gli account ancora fermi all'hash importato. Per un'importazione non arriva nulla al Suo webhook: il Suo sistema conosce già queste persone.
Due eccezioni. A un account importato con email_verified false, o senza la colonna, viene chiesto di confermare l'indirizzo la prima volta che accede, prima che la Sua applicazione lo riceva: dal 3 ottobre nessuna applicazione riceve un account il cui indirizzo nessuno ha confermato, importato o no. Marchi come verificato ciò che il vecchio provider aveva verificato, e niente di più. E una password più corta di 12 caratteri o più lunga di 256 accede comunque, ma non viene ricalcolata, perché è fuori dalle lunghezze che EAuth accetta per una nuova password; quell'account mantiene l'hash importato finché la persona non cambia la password, e il segnale nella console resta.
Una cosa da sapere su bcrypt
bcrypt usa solo i primi 72 byte di una password. Un utente con una password più lunga ha sempre effettuato l'accesso con quei 72 byte presso il provider precedente, e continua così fino al suo primo accesso su EAuth, quando l'intera password viene ricalcolata con Argon2id. Un piccolo miglioramento che nessuno deve chiedere, e un motivo per non stupirsi che una passphrase di 90 caratteri funzionasse prima e funzioni ancora.
Prima di registrarsi da qualsiasi parte
Legga la clausola sull'esportazione nelle condizioni prima dell'elenco delle funzioni. Se le condizioni tacciono sugli hash, dia per scontato che la risposta sia no. Se c'è una clausola e dice «su richiesta» o «previa verifica», metta in conto un ritardo che si misura in settimane, proprio nel momento in cui può permetterselo di meno. La clausola che vuole dice: in qualsiasi momento, senza chiedere, in un formato documentato, hash compresi.
Fonti
- Password Storage Cheat Sheet, OWASP, consultato il
- PHC Strings, C2SP, consultato il
- RFC 9106: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, IETF, consultato il
Scritto da Samuel Krauss, Founder. Archiviato in eauth, migration, passwords.
Tradotto dall’inglese. Leggi l’originale inglese