Autenticazione: nome utente (e-mail) e password hashed insieme in un campo di database

6

Attualmente sto sviluppando una piattaforma con un framework PHP per il nostro cliente.

Il responsabile del reparto IT del cliente ci chiede di gestire l'autenticazione con un campo di database contenente email + password + salt (hash), quindi non c'è un campo di posta elettronica in questa tabella e la password è più sicura (il suo ragionamento ). L'utente dovrebbe essere in grado di accedere con il suo indirizzo email e la sua password. Quindi l'indirizzo email funge da nome utente. L'idea alla base di questo è che gli indirizzi email degli utenti sono molto importanti per il business del nostro cliente e il responsabile IT vuole oscurare l'indirizzo email nella tabella di login in caso di un possibile attacco. (ad esempio, un hacker ottiene l'accesso alla tabella di accesso)

Questo è ovviamente possibile solo perché l'indirizzo email con hash per l'accesso è collegato al suo indirizzo email nella tabella del profilo. Fondamentalmente ci sono due tabelle che sono necessarie per il funzionamento di questo processo. Le tabelle sono nello stesso database, ovviamente. Una tabella di login con il campo della combinazione hash (email, pw, salt) e una tabella profilo che contiene tra l'altro l'e-mail in testo in chiaro in un campo. Chiamiamolo profile_email.

Ho caldamente raccomandato di non utilizzare questa soluzione, perché non ne ho mai sentito parlare e ho già identificato alcuni possibili problemi con questa soluzione.

Quindi le mie domande sono: è una soluzione sicura e fattibile? Riesci a pensare a problemi imprevedibili? Hai sentito parlare di soluzioni simili?

    
posta SEoCid86 12.10.2014 - 02:21
fonte

2 risposte

12

Per quanto posso dire, questo schema non ha alcun senso. Come hai notato, hai ancora bisogno di archiviare l'indirizzo email in chiaro per l'utente, quindi non c'è alcun vantaggio significativo sulla sicurezza dell'utilizzo dell'email in chiaro e dell'email + password + hash salato vs solo usando email in chiaro e password + hash salato.

Come sono sicuro che tu abbia già notato, senza l'e-mail in testo semplice (indipendentemente dal fatto che sia nella tabella del profilo o nella tabella di login) basarsi unicamente su un singolo valore hash di email + password + sale è impossibile (si passare attraverso ogni riga, ottenere il sale, calcolare l'hash, vedere se corrisponde, se non c'è corrispondenza, ottenere il sale dalla riga successiva, calcolare l'hash, vedere se corrisponde, ecc, ecc, ecc ...) e sarebbe un disastro per la sicurezza, perché consentirebbe a un utente malintenzionato di testare gli hash per tutti gli utenti del sito con un singolo tentativo di accesso rispetto alla sola possibilità di testare l'hash per un utente specifico.

Non vedo alcuna ragione per farlo. Non migliora la sicurezza, aumenta la complessità e l'implementazione è carica di pericoli. Dovresti educatamente, ma respingere con fermezza il cliente per seguire le migliori pratiche standard piuttosto che cercare di inventare il suo schema frenetico.

    
risposta data 12.10.2014 - 03:09
fonte
5

Potrebbero esserci problemi di comunicazione tra te e il responsabile del dipartimento IT? Come aveva già indicato Xander, un tale schema non funziona, e aggiungerei persino che è ridicolo. Per autenticare un utente, è necessario eseguire una ricerca del database sull'indirizzo email di accesso per recuperare l'hash corrispondente utilizzato per il confronto:

SELECT hash from Users WHERE email=?;
if($hash == hash_func($password)) then Grant access

Ciò che stai proponendo ora è rendere la ricerca più complicata aggiungendo un'operazione JOIN per evitare una ricerca diretta sulla tabella Users:

SELECT U.hash from Users U INNER JOIN Profile P WHERE P.id = U.id AND P.email=?;

Interrogare due tabelle che risiedono nello stesso database non migliora affatto la sicurezza. Renderà anche il processo di autenticazione più ingombrante e dispendioso dal punto di vista computazionale.

Se gli indirizzi email devono essere protetti, allora non può essere usato come parte del tuo schema di autenticazione. Un modo tipico per superare questo problema è utilizzare un nome utente in combinazione con la password. Ciò eliminerà la necessità di effettuare una ricerca in base all'indirizzo email:

SELECT hash from Users WHERE username=?;

Quindi ti consentirà inoltre di crittografare gli indirizzi email per proteggerli. Se il tuo database è ospitato su un server diverso dalla tua applicazione, chiunque riesca ad accedere al database potrebbe non essere in grado di recuperare gli indirizzi email.

Grazie per i chiarimenti. La risposta sopra è in risposta alla tua proposta come indicato nel terzo paragrafo della tua domanda. Come ho capito dal tuo commento qui sotto, il tuo cliente ha suggerito un approccio radicalmente diverso che non richiede l'uso di una seconda tabella (profilo):

SELECT id from Users WHERE hash=?;

Lo schema sopra è praticabile solo se assicuri che tutti gli hash nella tabella siano UNIQUE . Poiché non viene eseguita alcuna ricerca dell'email di accesso, è necessario risolvere i seguenti problemi di sicurezza:

  • come impedire la forzatura bruta su un singolo account
  • probabilità di abbinare un hash come il database diventa grande
  • capacità del tuo sito di gestire l'attacco DDOS sulla pagina di accesso poiché l'hashing viene sempre eseguito

A proposito, il tuo cliente accetta il rischio che un utente inserisca la password sbagliata e acceda come un altro utente? Se sì, allora puoi procedere con questo.

    
risposta data 12.10.2014 - 06:21
fonte

Leggi altre domande sui tag