Sostituire un hash di bcrypt con un hash non valido non ha alcuna possibile password di lavoro?

38

Ho un manager a cui piace "disattivare" gli account sostituendo l'hash bcrypt esistente nel database con un trattino semplice ( - ).

Questosembrafunzionareinquantolavecchiapasswordnonèpiùvalidaenonesisteunhashdibcryptvalidochepossacorrispondereaqualsiasialtrapassword.Maerocurioso,èefficaceocreaunrischioperlasicurezza?

Èunmodoefficacepernonutilizzarepasswordocreaunrischiomaggioreperlasicurezza?

QuestaspecificaimplementazioneutilizzalafunzionePHP password_verify ma vorrei che le risposte si concentrassero su qualsiasi implementazione generale. Per favore, non concentrarti sulle cattive pratiche del mio manager. Abbiamo anche un campo booleano per impostare l'utente su inattivo / attivo che credo sia migliore e più sicuro, ma non è quello su cui voglio concentrare le risposte.

    
posta Markus Tenghamn 11.06.2018 - 10:36
fonte

7 risposte

40

In termini di non autorizzare tentativi di accesso legittimi, va bene. A meno che tu non stia usando una funzione hash molto strana, non ci saranno valori che mappano a - , e previene attacchi di forza bruta contro i valori mancanti se il database viene rubato troppo, il che è positivo (erano improbabili , dato l'uso di bcrypt, ma questo si applica anche se l'implementazione utilizza un metodo terribile per la memorizzazione delle password - praticamente niente altro che il semplice testo).

In termini di aspetti negativi, se il database viene preso, diminuisce leggermente la sicurezza di altri account - l'autore dell'attacco ha meno record di forza bruta. Se stanno prestando attenzione, dovrebbero probabilmente rimuovere i record che sono contrassegnati come inattivi, ma comunque. Ho detto "leggermente" ...

Gli altri rischi potrebbero essere se ci sono metodi di accesso che consentono di bypassare il metodo hash per il confronto (ad esempio, si dispone di un metodo legacy che consente di fornire l'hash completo per qualche motivo) - in tal caso, se non si è controllando attentamente lo stato attivo, potrebbe consentire l'accesso fornendo un trattino. Idealmente, rimuovi questo metodo di accesso, se questo è il caso.

    
risposta data 11.06.2018 - 10:52
fonte
18

Un hash della password non valido (di solito "*") disabilita veramente l'autenticazione della password, poiché non c'è davvero alcun modo di fornire un valore che lo cancellerà. Tuttavia, un hash della password non valido non "disattiva" l'account se esistono altri metodi di autenticazione, ad es. dalla chiave privata ssh. In effetti, questo è un modo comune per forzare l'autenticazione solo tramite chiave: una password non valida in combinazione con una chiave pubblica ssh in ~user/.ssh . Pertanto un hash non valido nella colonna password non deve essere interpretato come "account inattivo", ma "autenticazione password bloccata".

Se l'accesso alla password è l'unico percorso disponibile, un hash non valido è probabilmente superiore alla segnalazione esplicita perché non ha bisogno del supporto software: se /etc/password ha una colonna activeuser e l'ho usata lasciando una password valida nel campo password, alcuni strumenti potrebbero ignorare il campo activeuser .

    
risposta data 11.06.2018 - 12:29
fonte
6

Certamente una grande differenza è che un utente contrassegnato come "inattivo" potrebbe ancora accedere, tranne il server controlla la flag e gestisce correttamente il tentativo. Inoltre, il flag può essere rimosso, ripristinando in modo efficace lo stato originale, mentre non è possibile ripristinare l'hash su "-" senza salvare l'hash della password da qualche altra parte. A seconda dell'applicazione, questo potrebbe essere o meno il comportamento desiderato.

Un rischio di sicurezza non viene creato da questo approccio, poiché un utente malintenzionato con accesso al tuo database potrebbe semplicemente vedere che questo utente non dovrebbe essere in grado di accedere. Come hai affermato correttamente, nessun hash di bcrypt può corrispondere "- ", poiché il formato da solo non corrisponde.

Come affermato da schroeder nei commenti, questa non è una cattiva pratica, ma un concetto comune per impedire agli utenti di accedere, senza modificare il meccanismo di accesso per tenere conto del proprio flag "inattivo" (utenti inattivi che tentano di accedere sono implicitamente rifiutati).

    
risposta data 11.06.2018 - 10:51
fonte
6

Lo scopo degli hash sicuri è quello di rendere difficile la forzatura delle password nel database. Se è possibile decifrare o addirittura indovinare la password dal "semplice hash", le password dell'account sono a rischio.

Ma non è tutta la storia. Se lo scopo è semplicemente di invalidare chiunque dall'essere in grado di utilizzare o indovinare la password dal lato client, allora funziona perfettamente. Questo metodo è stato usato per molto tempo. Ma le voci della password sul back-end sono indebolite. Questo potrebbe andar bene se ci sono altri controlli e i rischi e gli impatti del compromesso dell'account sono bassi.

    
risposta data 11.06.2018 - 10:51
fonte
5

Questo è un altro sulla stessa falsariga di altre risposte, quindi vorrei prima reiterare il punto principale: questo può essere un modo efficace per invalidare gli utenti se non ci sono altri modi in . Come esempio a cui prestare attenzione:

In che modo il tuo sistema gestisce gli utenti registrati? Presumibilmente, una volta che un utente si connette al sistema, si ricorda di esso fino a quando non si disconnettono, probabilmente con cookie / sessioni. Cosa memorizzi nella sessione per assicurarti che il tuo utente rimanga connesso? Ancora più importante, cosa succede se un utente ha effettuato l'accesso e quindi il suo hash della password è stato invalidato? Se si memorizza la password stessa nella sessione, verranno immediatamente disconnessi, ma memorizzare la password nella sessione sarebbe una cattiva idea. Se memorizzi l'hash della password nella sessione, verranno immediatamente disconnessi. Se tuttavia nella sessione si registra semplicemente il fatto che sono connessi e l'id dell'utente che ha effettuato l'accesso come, l'invalidazione dell'hash non disconnetterà automaticamente tutti gli utenti attualmente connessi. Lo considererei un problema, specialmente se hai sessioni di lunga durata. Cosa succede se si disattiva l'hash di qualcuno e una settimana dopo aprono il browser e sono comunque connessi? Questo è peggio se la funzione "Aggiorna password" che fornisci agli utenti non richiede di convalidare le loro vecchie password. In tal caso, qualcuno che ha già effettuato l'accesso può rimanere connesso quando si disattiva il proprio hash e quindi essere in grado di cambiare la propria password e riguadagnare un hash valido, riattivando il proprio account.

Fai attenzione anche alle chiavi API. Alcuni sistemi (Gitlab ha avuto un po 'di flessibilità per fare ciò prima di aver cambiato i loro sistemi) hanno chiavi API longevi utilizzate per l'accesso API. Un utente che conosce la sua chiave API può continuare a utilizzare il sistema anche se il suo hash della password è cambiato.

Dato il concetto generale di difesa in profondità, voterei personalmente per avere una procedura di disattivazione "formale" nel tuo sistema (di solito ho solo una colonna di stato nella tabella utente che viene controllata durante il normale flusso di autenticazione / permesso). Dopo tutto, ci possono essere molti avvertimenti che potrebbero comportare che un utente con un hash disattivato sia ancora in grado di utilizzare il sistema. Ovviamente, la sicurezza è sempre un approccio costo / beneficio per ogni entità, quindi se aggiungere un flag di disattivazione formale richiede troppo tempo per il tuo sistema, e nessuna delle vie di "attacco" nelle risposte qui sembrano applicabili a te, allora sei probabilmente bene.

    
risposta data 11.06.2018 - 14:34
fonte
3

Sì, questo è il modo standard in Unix, ed è stato per secoli.

La shadow (5) pagina di manuale risponde esplicitamente alla tua domanda:

       If the password field contains some string that is not a valid
       result of crypt(3), for instance ! or *, the user will not be
       able to use a unix password to log in (but the user may log in
       the system by other means).

Ci sono altri trucchi, ad es. passwd (1) ha un'opzione --lock :

   -l, --lock
       Lock the password of the named account. This option disables a
       password by changing it to a value which matches no possible
       encrypted value (it adds a ´!´ at the beginning of the password).

       Note that this does not disable the account. The user may still
       be able to login using another authentication token (e.g. an SSH
       key). To disable the account, administrators should use usermod
       --expiredate 1 (this set the account's expire date to Jan 2,
       1970).

       Users with a locked password are not allowed to change their
       password.
    
risposta data 13.06.2018 - 08:09
fonte
2

La prima cosa da notare è che un "hash della password" non è semplicemente un hash della password, è una struttura multi-campo che contiene non solo l'hash stesso ma un'indicazione di quale schema di hashing è utilizzato e di tutti i parametri necessari (nel caso di bcrypt a salt e un parametro di costo)

Quindi la risposta alla domanda se un "hash password" non valido non ha alcuna password funzionante non ha nulla a che fare con le funzioni hash, si riduce a come il codice di controllo gestisce gli input che non rappresentano un hash di password valido in uno dei formati supportati. Si spera che considererebbe un hash non valido come non corrispondente, ma la documentazione non è chiara, quindi dobbiamo leggere la fonte.

link

link

Leggendo il codice per php's password_verify troviamo che prima chiama "php_password_determine_algo", se la password inizia con $ 2y $ è considerato come "bcrypt", se inizia con "$ argon2i $" è considerato come argon2 , altrimenti è considerato "sconosciuto".

Se l'hash è "bcrypt" o "unknown" passa poi a chiamare php_crypt passandogli la password e l'hash, questo tenta di eseguire l'hash della password fornita usando il metodo e salt dalla password esistente, può farlo sia utilizzando un'implementazione interna o chiamando la funzione crypt del sistema operativo. Sembra che in caso di hash esistente non valido, il codice interno ricadrà su DES vecchia scuola, non è sicuro di quale sarà l'implementazione del sistema.

Tornando alla sezione sconosciuta / bcrypt in password_verify sembra che non riesca a corrispondere se una delle seguenti condizioni è vera.

  1. php_crypt restituisce un errore.
  2. la lunghezza dell'hash restituita da php_crypt non corrisponde alla lunghezza dell'hash passweed a password_verify
  3. l'hash passato a password_verify è inferiore a 13 caratteri di lunghezza
  4. il contenuto dell'hash restituito da php_crypt non corrisponde al contenuto dell'hash passato a password_verify

Il tuo hash di "-" verrà rifiutato dalla regola 3 almeno da questo elenco (probabilmente anche la regola 1 o 2, ma ciò dipende dal comportamento dell'implementazione della criptazione utilizzata).

    
risposta data 12.06.2018 - 07:15
fonte

Leggi altre domande sui tag