Crediamo che Stack Overflow non dovrebbe essere solo una risorsa per domande tecniche molto specifiche, ma anche per linee guida generali su come risolvere varianti di problemi comuni.
Daremo per scontato che tu sappia già come costruire un modulo HTML di login+password che invia i valori ad uno script sul lato server per l'autenticazione. Le sezioni che seguono tratteranno i modelli per una solida autenticazione pratica, e come evitare i più comuni trabocchetti della sicurezza. A HTTPS o non HTTPS? A meno che la connessione non sia già sicura (cioè, tunnelata attraverso HTTPS usando SSL/TLS), i valori del tuo modulo di login saranno inviati in chiaro, il che permette a chiunque intercetti la linea tra il browser e il server web di leggere i login mentre passano. Questo tipo di intercettazione è fatto abitualmente dai governi, ma in generale, non affronteremo 'owned'wires se non per dire questo: Basta usare HTTPS. In sostanza, l'unico modo pratico per proteggersi dal wiretapping/sniffing dei pacchetti durante il login è usando HTTPS o un altro schema di crittografia basato sul certificato (per esempio, TLS) o un collaudato & schema challenge-response (per esempio, l'SRP basato su Diffie-Hellman). Qualsiasi altro metodo può essere facilmente aggirato da un attaccante in grado di origliare. Naturalmente, se si è disposti a diventare un po' poco pratici, si potrebbe anche impiegare una qualche forma di schema di autenticazione a due fattori (ad esempio l'applicazione Google Authenticator, un cifrario fisico stile guerra fredda, o un dongle generatore di chiavi RSA). Se applicato correttamente, questo potrebbe funzionare anche con una connessione non protetta, ma è difficile immaginare che un sviluppatore sia disposto a implementare l'autenticazione a due fattori ma non SSL. (Non) Roll-your-own JavaScript encryption/hashing Dato il costo percepito (anche se ora evitabile) e la difficoltà tecnica di impostare un certificato SSL sul vostro sito web, alcuni sviluppatori sono tentati di rollare il proprio hashing in-browser o schemi di crittografia al fine di evitare di passare login in chiaro su un filo non protetto. Anche se questo è un pensiero nobile, è essenzialmente inutile (e può essere una falla di sicurezza) a meno che non sia combinato con uno dei precedenti - cioè, o assicurando la linea con una crittografia forte o utilizzando un collaudato meccanismo di sfida-risposta (se non sapete cosa sia, sappiate che è uno dei concetti più difficili da dimostrare, più difficili da progettare, e più difficili da implementare nella sicurezza digitale). Mentre è vero che l'hashing della password può essere efficace contro la divulgazione della password, è vulnerabile agli attacchi di replay, agli attacchi Man-In-The-Middle / hijackings (se un attaccante può iniettare alcuni byte nella tua pagina HTML non protetta prima che raggiunga il tuo browser, può semplicemente commentare l'hashing nel JavaScript), o agli attacchi di forza bruta (poiché stai consegnando all'attaccante sia il nome utente, il sale e la password hashata). CAPTCHAS contro l'umanità CAPTCHA ha lo scopo di contrastare una specifica categoria di attacchi: dizionario automatico/brute force trial-and-error senza operatore umano. Non c'è dubbio che questa sia una minaccia reale, tuttavia, ci sono modi per affrontarla senza soluzione di continuità che non richiedono un CAPTCHA, in particolare schemi di blocco del login lato server progettati correttamente - ne parleremo più avanti. Sappiate che le implementazioni CAPTCHA non sono create allo stesso modo; spesso non sono risolvibili dall'uomo, la maggior parte di esse sono in realtà inefficaci contro i bot, tutte sono inefficaci contro il lavoro a basso costo del terzo mondo (secondo OWASP, l'attuale tasso di sfruttamento è di 12 dollari per 500 test), e alcune implementazioni possono essere tecnicamente illegali in alcuni paesi (vedi OWASP Authentication Cheat Sheet). Se dovete usare un CAPTCHA, usate Google reCAPTCHA, dato che è OCR-hard per definizione (dato che usa scansioni di libri già OCR-miscelati) e si sforza molto di essere user-friendly. Personalmente, tendo a trovare i CAPTCHAS fastidiosi, e li uso solo come ultima risorsa quando un utente ha fallito il login un certo numero di volte e i ritardi di throttling sono massimi. Questo accadrà abbastanza raramente da essere accettabile, e rafforza il sistema nel suo complesso. Memorizzazione delle password / Verifica dei login Questo potrebbe finalmente essere una conoscenza comune dopo tutti gli hack altamente pubblicizzati e le perdite di dati degli utenti che abbiamo visto negli ultimi anni, ma deve essere detto: Non memorizzate le password in chiaro nel vostro database. I database degli utenti sono abitualmente violati, trapelati o ottenuti attraverso l'iniezione SQL, e se state memorizzando password grezze, in chiaro, questo è un gioco istantaneo per la vostra sicurezza di login. Quindi, se non si può memorizzare la password, come si fa a controllare che la combinazione login+password postata dal modulo di login sia corretta? La risposta è l'hashing usando una funzione di derivazione della chiave. Ogni volta che viene creato un nuovo utente o viene cambiata una password, si prende la password e la si fa passare attraverso una KDF, come Argon2, bcrypt, scrypt o PBKDF2, trasformando la password in chiaro ("correcthorsebatterystaple") in una lunga stringa dall'aspetto casuale, che è molto più sicura da memorizzare nel vostro database. Per verificare un login, si esegue la stessa funzione hash sulla password inserita, questa volta passando il sale e si confronta la stringa hash risultante con il valore memorizzato nel database. Argon2, bcrypt e scrypt memorizzano già il sale con l'hash. Guardate questo articolo su sec.stackexchange per informazioni più dettagliate. La ragione per cui viene usato un sale è che l'hashing di per sé non è sufficiente - vorrete aggiungere un cosiddetto 'sale' per proteggere l'hash da tabelle arcobaleno. Un sale impedisce efficacemente che due password che corrispondono esattamente siano memorizzate come lo stesso valore di hash, impedendo che l'intero database sia scansionato in una sola volta se un attaccante sta eseguendo un attacco di password guessing. Un hash crittografico non dovrebbe essere usato per la memorizzazione delle password perché le password selezionate dall'utente non sono abbastanza forti (cioè di solito non contengono abbastanza entropia) e un attacco di password guessing potrebbe essere completato in un tempo relativamente breve da un attaccante con accesso agli hash. Questo è il motivo per cui vengono usate le KDF - queste effettivamente "allungano la chiave", il che significa che ogni password indovinata da un attaccante causa ripetizioni multiple dell'algoritmo di hash, per esempio 10.000 volte, il che fa sì che l'attaccante indovini la password 10.000 volte più lentamente. Dati di sessione - "Sei loggato come Spiderman69" Una volta che il server ha verificato il login e la password rispetto al vostro database utenti e ha trovato una corrispondenza, il sistema ha bisogno di un modo per ricordare che il browser è stato autenticato. Questo fatto dovrebbe essere memorizzato solo lato server nei dati di sessione. Se non avete familiarità con i dati di sessione, ecco come funziona: Una singola stringa generata in modo casuale viene memorizzata in un cookie in scadenza e utilizzata per fare riferimento a una collezione di dati - i dati di sessione - che vengono memorizzati sul server. Se state usando un framework MVC, questo è senza dubbio già gestito. Se possibile, assicuratevi che il cookie di sessione abbia i flag secure e HTTP Only impostati quando viene inviato al browser. Il flag HttpOnly fornisce una certa protezione contro la lettura del cookie attraverso un attacco XSS. Il flag secure assicura che il cookie sia rimandato indietro solo via HTTPS, e quindi protegge da attacchi di sniffing della rete. Il valore del cookie non dovrebbe essere prevedibile. Se viene presentato un cookie che fa riferimento a una sessione inesistente, il suo valore dovrebbe essere sostituito immediatamente per prevenire la fissazione della sessione.
I cookie di accesso persistenti (funzionalità "ricordami") sono una zona pericolosa; da un lato, sono completamente sicuri come i login convenzionali quando gli utenti capiscono come gestirli; e dall'altro, sono un enorme rischio per la sicurezza nelle mani di utenti disattenti, che possono usarli su computer pubblici e dimenticare di fare il logout, e che possono non sapere cosa sono i cookie del browser o come cancellarli. Personalmente, mi piacciono i login persistenti per i siti web che visito regolarmente, ma so come gestirli in modo sicuro. Se siete sicuri che i vostri utenti sanno lo stesso, potete usare i login persistenti con la coscienza pulita. In caso contrario - beh, allora si può sottoscrivere la filosofia che gli utenti che sono negligenti con le loro credenziali di accesso se la sono cercata se vengono hackerati. Non è come se andassimo a casa dei nostri utenti e strappassimo tutti quei post-it con le password che hanno allineato sul bordo dei loro monitor. Naturalmente, alcuni sistemi non possono permettersi di avere nessun account violato; per tali sistemi, non c'è modo di giustificare la presenza di login persistenti. Se decidete di implementare i cookie di login persistenti, ecco come fare:.
Non implementare 'domande segrete'. La funzione 'domande segrete'è un anti-pattern di sicurezza. Leggete il documento dal link numero 4 della lista MUST-READ. Potete chiederlo a Sarah Palin, dopo che il suo account e-mail Yahoo! è stato violato durante una precedente campagna presidenziale perché la risposta alla sua domanda di sicurezza era... "Wasilla High School"! Anche con le domande specificate dall'utente, è altamente probabile che la maggior parte degli utenti scelga o:
Ho già menzionato il motivo per cui non dovreste mai usare domande di sicurezza per gestire le password dimenticate/perdute degli utenti; va anche da sé che non dovreste mai mandare via e-mail agli utenti le loro vere password. Ci sono almeno altri due trabocchetti troppo comuni da evitare in questo campo:
Per prima cosa, vorrai leggere questo piccolo articolo per un controllo della realtà: Le 500 password più comuni Ok, forse la lista non è la lista canonica delle password più comuni su qualsiasi sistema ovunque, ma è una buona indicazione di quanto male le persone scelgano le loro password quando non c'è una politica applicata. Inoltre, l'elenco sembra spaventosamente vicino a casa quando lo si confronta con le analisi pubblicamente disponibili delle password rubate di recente. Quindi: Senza requisiti minimi di forza della password, il 2% degli utenti usa una delle 20 password più comuni. Ciò significa: se un aggressore ottiene solo 20 tentativi, 1 su 50 account sul tuo sito web sarà craccabile. Per contrastare questo fenomeno è necessario calcolare l'entropia di una password e poi applicare una soglia. Il National Institute of Standards and Technology (NIST) Special Publication 800-63 ha una serie di suggerimenti molto buoni. Questo, se combinato con un dizionario e un'analisi del layout della tastiera (per esempio, 'qwertyuiop' è una cattiva password), può rifiutare il 99% di tutte le password mal selezionate ad un livello di 18 bit di entropia. Calcolare semplicemente la forza della password e mostrare un misuratore visivo della forza all'utente è buono, ma insufficiente. A meno che non sia imposto, molti utenti molto probabilmente lo ignoreranno. E per una rinfrescata sulla facilità d'uso delle password ad alta intensità, Randall Munroe Password Strength xkcd è altamente raccomandato. Utilizzate Troy Hunt Have I Been Pwned API per controllare le password degli utenti rispetto alle password compromesse in violazioni di dati pubblici.
Per prima cosa, dai un'occhiata ai numeri: Velocità di recupero password - Quanto resisterà la tua password Se non hai il tempo di guardare le tabelle in quel link, ecco la lista:
Solo come un inciso, gli attaccanti più avanzati cercheranno di aggirare il login throttling 'diffondendo le loro attività':
Le credenziali possono essere compromesse, sia da exploit, sia da password scritte e perse, sia da computer portatili con chiavi rubate, sia da utenti che inseriscono login in siti di phishing. I login possono essere ulteriormente protetti con l'autenticazione a due fattori, che utilizza fattori fuori banda come i codici monouso ricevuti da una telefonata, un messaggio SMS, un'app o un dongle. Diversi provider offrono servizi di autenticazione a due fattori. L'autenticazione può essere completamente delegata a un servizio single-sign-on, dove un altro provider gestisce la raccolta delle credenziali. Questo spinge il problema a una terza parte fidata. Google e Twitter forniscono entrambi servizi SSO basati su standard, mentre Facebook fornisce una soluzione proprietaria simile.
L'unico modo pratico per inviare le credenziali in modo sicuro al 100% è usando SSL. Usare JavaScript per fare l'hash della password non è sicuro. Insidie comuni per l'hash delle password lato client:
Non memorizzare mai le password come testo in chiaro nel database. Nemmeno se non ti interessa la sicurezza del tuo sito. Supponiamo che alcuni dei tuoi utenti riutilizzino la password del loro conto bancario online. Quindi, conservate la password in hash, e buttate via l'originale. E assicuratevi che la password non appaia nei log di accesso o nei log delle applicazioni. OWASP raccomanda l'uso di Argon2 come prima scelta per le nuove applicazioni. Se questo non è disponibile, PBKDF2 o scrypt dovrebbero essere usati al suo posto. E infine, se nessuno dei precedenti è disponibile, usate bcrypt. Gli hash da soli sono anche insicuri. Per esempio, password identiche significano hash identici - questo rende le tabelle di ricerca degli hash un modo efficace per decifrare molte password in una volta sola. Invece, memorizzate l'hash salato. Un sale è una stringa aggiunta alla password prima dell'hashing - usate un sale diverso (casuale) per ogni utente. Il sale è un valore pubblico, quindi potete memorizzarlo con l'hash nel database. Vedi qui per saperne di più. Questo significa che non puoi inviare agli utenti le loro password dimenticate (perché hai solo l'hash). Non resettare la password dell'utente a meno che tu non abbia autenticato l'utente (gli utenti devono provare che sono in grado di leggere le email inviate all'indirizzo email memorizzato (e validato)).
Le domande di sicurezza sono insicure - evita di usarle. Perché? Qualsiasi cosa faccia una domanda di sicurezza, una password la fa meglio. Leggi Parte III: Usare le domande segrete in risposta di @Jens Roland qui in questo wiki.
Dopo che l'utente fa il login, il server invia all'utente un cookie di sessione. Il server può recuperare il nome utente o l'id dal cookie, ma nessun altro può generare un tale cookie (TODO spiegare i meccanismi). I cookie possono essere dirottati: sono sicuri solo quanto il resto della macchina del cliente e le altre comunicazioni. Possono essere letti dal disco, sniffati nel traffico di rete, sollevati da un attacco di cross-site scripting, rubati da un DNS avvelenato in modo che il client invii i suoi cookie ai server sbagliati. Non inviare cookie persistenti. I cookie dovrebbero scadere alla fine della sessione del client (chiusura del browser o uscita dal tuo dominio). Se volete autologare i vostri utenti, potete impostare un cookie persistente, ma dovrebbe essere distinto da un cookie di sessione completa. Potete impostare un flag aggiuntivo che l'utente si è autologato, e ha bisogno di loggarsi per davvero per operazioni sensibili. Questo è popolare con i siti di shopping che vogliono fornire all'utente un'esperienza di acquisto personalizzata senza soluzione di continuità, ma proteggendo comunque i suoi dettagli finanziari. Per esempio, quando torni a visitare Amazon, ti mostrano una pagina che sembra che tu sia loggato, ma quando vai a fare un ordine (o a cambiare l'indirizzo di spedizione, la carta di credito, ecc), ti chiedono di confermare la tua password. I siti web finanziari come banche e carte di credito, d'altra parte, hanno solo dati sensibili e non dovrebbero permettere l'auto-login o una modalità a bassa sicurezza.
In primo luogo, un forte avvertimento che questa risposta non è la migliore per questa esatta domanda. Non dovrebbe assolutamente essere la prima risposta!
Andrò avanti e menzionerò il BrowserID proposto da Mozilla (o forse più precisamente, il Verified Email Protocol) nello spirito di trovare un percorso di aggiornamento per approcci migliori all'autenticazione in futuro.
Lo riassumerò in questo modo:
@
dominio" è concisa e supportata da una vasta gamma di protocolli e schemi URI. Un tale identificatore è, ovviamente, universalmente riconosciuto come un indirizzo e-mail.Questo non è strettamente "autenticazione basata su moduli per siti web". Ma è uno sforzo per passare dalla norma attuale di autenticazione basata su moduli a qualcosa di più sicuro: l'autenticazione supportata dal browser.