back to top

Sicurezza PHP: come archiviare password e creare sistemi di login sicuri

Le password sono la principale linea di difesa contro l’accesso non autorizzato alle informazioni dei propri account sul web e, fin troppo spesso, puรฒ capitare di trovarsi dietro un progetto che le archivia con un hashing debole oppure, peggio ancora, salvate in chiaro sul database, vuoi perchรฉ si tratta di un progetto vecchio e mai revisionato oppure a causa di informazioni datate reperite sul web da parte dello sviluppatore.

C’รจ da precisare innanzitutto che le fondamenta per la sicurezza della password iniziano dalla password stessa e se per un vostro utente la password ideale รจ 123456 allora nessun sistema di sicurezza, per quanto articolato, sarร  in grado di difenderla efficacemente.

Pubblicitร 

Da questo punto di vista รจ buona norma prendere in considerazione l’ipotesi di creare una pagina informativa per “educare” gli utenti alla scelta di password elaborate, Google ad esempio fornisce una serie di indicazioni utili per gli utenti su come creare una password forte.

L’argomento รจ molto vasto ma proveremo a riassumere in pillole quelli che sono gli errori piรน comuni e le buone pratiche da adottare per trattare le password nella vostra applicazione in modo sicuro. Quali sono, quindi, le cattive abitudini che uno sviluppatore deve evitare se vuole mettere in sicurezza i propri progetti?

Best practices per lo sviluppo di sistemi di login

  • Non reinventare le meccaniche di sicurezza – Innanzitutto non bisogna improvvisarsi esperti di sicurezza: รจ assolutamente da evitare la costruzione di meccanismi di codifica o di logiche personali di sicurezza.
  • Non adoperare MD5() – Non adoperate mai l’algoritmo md5 per l’hashing della password anche se precedentemente l’avete criptata con altri metodi piรน sicuri poichรฉ, a causa della possibilitร  di collisione dell’algoritmo, sarebbe molto facile per un attaccante trovare velocemente una stringa che risulti come password valida anche se non รจ quella definita in partenza dall’utente, vanificando quindi tutti i vostri sforzi.
  • Non utilizzare un salt unico per tutte le password – La condizione ideale per proteggere le password รจ che, se anche l’intero sistema รจ conosciuto alla perfezione dal nostro attaccante (vuoi perchรฉ รจ riuscito a recuperare i sorgenti in qualche modo o altro motivo), senza la chiave crittografica risulti molto difficile risalire al dato originario, di conseguenza il salt non puรฒ essere un valore statico.
  • Mai archiviare una password su un cookie, anche se sotto hash – Il cookie รจ il posto piรน insicuro in cui archiviare la password, potrebbe essere facilmente intercettato da un attaccante al fine di recuperare il dato di interesse. Anche se la password fosse criptata, l’attaccante avrebbe tutto il tempo necessario per eseguire un attacco a forza bruta su una sua macchina ottimizzata a tal fine, oppure tentare l’utilizzo di attacchi a dizionario per scovare in tempi ragionevoli il dato.

Cosa fare per proteggere adeguatamente le password?

  • Utilizzare i mezzi appropriati – Fate affidamento sugli strumenti che PHP giร  offre. Utilizzare un algoritmo di hashing รจ l’opzione migliore che avete a disposizione e sfruttare funzioni come ad esempio il crypt oppure password_hash (PHP>=5.5) vi permetterร  di implementare molto semplicemente una logica di sicurezza piรน che valida.
  • Adoperare un algortimo di hashing lento – Quando si parla di sicurezza non si parla di prestazioni e questo argomento deve finire in secondo piano: la lentezza dell’algoritmo farร  si che un attacco a forza bruta impieghi molto piรน tempo per proporre tutte le possibili combinazioni. Personalmente suggerisco di adoperare il blowfish che php integra nativamente allo scopo.
  • Utilizzare un salt casuale crittograficamente sicuro – Il salt deve essere qualcosa che un possibile attaccante non puรฒ conoscere e che non puรฒ predire ma soprattutto deve essere casuale per ogni password con cui si usa. In questo modo nessuno degli hash memorizzati sul database sarร  uguale a quello di un altro utente, anche se entrambi usano la stessa password. Inoltre un buon salt rende vano l’uso delle rainbow table da parte di un attaccante nel caso riesca a recuperare l’elenco degli hash associati agli utenti.
  • Utilizzare una connessione sicura quando possibile – Quando una password viaggia dal computer dell’utente al server lo fa in chiaro attraverso la rete. Questo renderebbe possibile per un attaccante, nelle giuste condizioni, la possibilitร  di intercettarla prima ancora che questa venga protetta dai vari processi di sicurezza della nostra applicazione. L’utilizzo di una connessione sicura garantirร  invece che ogni informazione scambiata con l’utente viaggi criptata attraverso la rete, rendendo cosรฌ impossibile questo genere di attacchi.

La sicurezza non si basa perรฒ solo sul modo in cui si conserva il dato. Pertanto รจ consigliabile:

  • Richiedete l’immissione di password piรน articolate – Vietate agli utenti l’utilizzo di password lunghe meno di 8 caratteri e suggerite l’uso di lettere maiuscole, minuscole, numeri e qualche carattere speciale. Non c’รจ motivo di limitare la lunghezza della password o di bloccare determinati caratteri, tutt’anzi.
  • Limitare il numero di tentativi dei login – Limitate ad un numero ragionevole i tentativi falliti di login, se quel numero viene raggiunto bloccate l’account e obbligatelo a riattivarlo con una conferma tramite email.
  • Proporre agli utenti la modifica periodica della password – Una cosa che bisogna aver chiaro รจ che nessuna password, criptata in qualsiasi modo, รจ al sicuro per sempre: a seconda del metodo utilizzato un elaboratore puรฒ impiegare anche diversi mesi a compiere i tentativi necessari per scovare una password, di conseguenza รจ importante segnalare agli utenti la necessitร  di impostare una nuova password dopo un ragionevole periodo di 6 mesi dall’ultima modifica.

Memorizzazione e verifica password utente con PHP

PHP fortunatamente ci mette a disposizione diversi strumenti utili, in particolare ecco come generare un hash da una password mediante la funzione crypt:

// Password fornita dall'utente tramite form
$password = 'Password utente';

// Generiamo un salt casuale crittograficamente sicuro
$salt = mcrypt_create_iv(32, MCRYPT_DEV_URANDOM);

// Rendiamo il salt compatibile con la sintassi dell'hash che stiamo per usare
$salt = '$2a$10$' . strtr(base64_encode($salt), '+', '.');

// Codifichiamo la password in un hash a 60 caratteri di lunghezza
$hash = crypt($password, $salt);

// A questo punto รจ $hash che bisogna salvare nel database

Se invece avete a disposizione PHP v5.5 o superiore, potete semplificare il processo in questo modo:

// Password fornita dall'utente tramite form
$password = 'Password utente';

// Codifichiamo la password in un hash a 60 caratteri di lunghezza
$hash = password_hash($password, PASSWORD_BCRYPT);

// A questo punto $hash รจ il dato da archiviare nel database.

E fin qui abbiamo visto come produrre un hash sicuro. Vediamo adesso in che modo eseguire i controlli di verifica come, ad esempio, nella procedura di login della vostra applicazione.

// Hash recuperato dal database e password fornita dall'utente tramite modulo form
$hash = '...';
$password = 'Password utente';

if (crypt($password, $hash) === $hash) {
  // Password corretta!
} else {
  // Password invalida!
}

Con PHP v5.5 o superiore, esiste invece la funzione password_verify:

// Hash recuperato dal database e password fornita dall'utente tramite modulo form
$hash = '...';
$password = 'Password utente';

if (password_verify($password, $hash)) {
  // Password corretta!
} else {
  // Password invalida!
}

In ultimo, una regola d’oro da tenere in considerazione รจ di avere sempre a portata la documentazione ufficiale di PHP delle funzioni coinvolte per avere ben presente le varie possibilitร  e i comportamenti previsti nei vari casi di utilizzo.

Altri contenuti interessanti

Pubblicitร 

Leggi anche...

Dominio scaduto da rinnovare subito? No, รจ una truffa!

Negli ultimi anni si รจ assistito a un aumento...

Aggiornamento sito web: perchรฉ รจ importante e deve essere fatto con regolaritร 

Lโ€™aggiornamento di un sito web รจ unโ€™attivitร  fondamentale che...

Autenticazione a due fattori (2FA): cos’è e come funziona

L'autenticazione a due fattori (in inglese Two Factor Authentication...

Authcode: cos’è e come funziona

Con il termine Authcode (o Auth-code) si fa riferimento...

HTTP Security Headers: aumentare la sicurezza del sito con .htaccess

Esistono diverse tecniche per innalzare il livello di sicurezza...

Criptare (e decriptare) file su Linux con OpenSSL

OpenSSL è un'implementazione rilasciata sotto licenza Open Source dei...
Pubblicitร