2009-03-03 9 views
11

Dopo aver postato this qualche tempo fa, ho deciso di creare la mia capacità di registrazione/autenticazione in PHP. Mi piacerebbe a chiunque di segnalare i difetti/opportunità di miglioramento, in particolare in tutto ciò che è memorizzato nella sessione di ...Si prega di criticare i miei sforzi di autenticazione PHP

Il flusso logico è:

1 - utente si registra utilizzando e-mail come nome utente, un "sito nome "che poi fa parte di qualsiasi url cui avranno accesso e una password di almeno 6 caratteri che deve contenere lettere e numeri (so che potrebbe essere più forte)

2 - A condizione che l'utente e il sito siano unici , Li memorizzo entrambi, insieme a una stringa generata a caso (salt) in una riga nella tabella auth nel mio database. Quindi prendo la password dell'utente, concatenando il sale e archiviato un hash MD5 di questa password salata nella stessa riga di database

3 - Quando un utente effettua il login, prendo la password che ha inserito e concatena il sale ad esso, creare un hash MD5 di questo e confrontarlo con quello che ho memorizzato nel database - se corrispondono, l'utente ha inserito la password corretta e il loro nome utente viene scritto nella sessione

4 - Su ogni richiesta, utilizzo il nome utente memorizzato nella sessione per interrogare il database e leggere il nome del sito associato a questo utente. Poi lo paragono al nome del sito nell'URL stesso, e se corrispondono corrispondono a una variabile accessibile al resto o allo script (non una variabile globale, è solo leggibile dal mio controller che decide se un utente può vedere una pagina particolare) se i due nomi dei siti non corrispondono, l'utente viene reindirizzato al login

La mia preoccupazione è che qualcuno possa scrivere nella sessione e quindi essere in grado di accedere alle pagine delle persone se conoscono il nome utente che hanno firmato con? Come faresti a prevenire questo?

Prima che qualcuno mi accusi di negligenza dal modo in cui questo è un progetto personale per l'apprendimento - Non sto esponendo i dati dei clienti!

+0

È consigliabile riutilizzare un framework di autenticazione esistente quando possibile, perché, in realtà, è complesso. Ad esempio, dai un'occhiata a https://github.com/delight-im/PHP-Auth che è sia agnostico che indipendente dal database. – caw

risposta

1

Se qualcuno sta guardando l'invio del modulo di registrazione, allora hanno le informazioni che ti riguardano lo scopriranno. Primo passo: usa HTTPS per i tuoi moduli.

Per quanto riguarda la roba db crittografata, lascerò che qualcun altro se ne occupi. :-)

8
  1. Perché 6 caratteri? Rendila più grande e richiede un minimo di 6 (o più) personaggi. Non ci sono scuse per limitare il numero di caratteri nella password a 6.

  2. Mettere più del nome utente nella sessione. Ma per farlo in modo sicuro, è necessario modificare il sale ogni accesso:

A- Dalla pagina di accesso: verificare nome e password con sale esistente. Se valido aggiorna la tabella utente salt e password con un nuovo salt (hai la password da parte dell'utente in modo da poter md5 e il sale di nuovo). Scrivi l'md5 della password per la sessione. B- Da qualsiasi altra pagina: confronta la password utente e hash con il database. Se non corrispondono, reindirizza alla pagina di accesso.

Il difetto con questa idea è che l'utente non può mantenere gli accessi su più macchine/browser.

Il sistema di registrazione deve funzionare. Come sai che l'indirizzo e-mail è valido?Come sai che la registrazione dell'utente possiede l'indirizzo email? Devi inviare un'email all'indirizzo contenente un link al tuo sito che deve essere cliccato prima di consentire all'account di accedere a qualsiasi cosa. Altrimenti qualcuno può iscriversi sotto l'indirizzo di posta elettronica di qualcun altro fare affermazioni fraudolente come quella persona o semplicemente causare il tuo sito a spam quella persona che ha chiuso il tuo sito.

Si potrebbe anche voler indagare su CAPTCHA per limitare le registrazioni programmate.

+0

Grazie Joe - Re 6 caratteri, è già almeno 6 anziché esattamente 6, modificherò per chiarire. Ri scrivendo la password per la sessione, è l'idea di scrivere qualcosa di diverso ogni volta, in modo che i dati della sessione rubati siano validi solo fino al login? –

+0

Sì. Altrimenti qualcuno può riutilizzare la sessione per sempre (o fino a quando l'utente non cambia la sua password.Alcuni direbbero che il valore dovrebbe cambiare ogni pagina ma poi è necessario memorizzare la password non elaborata nella sessione.Per dire che per me ha meno senso – jmucchiello

3

Risposta breve: sembra buono!

Risposta lunga:

  1. Sì, si dovrebbe consentire forti password/più lunghi, ma per il resto questo è ok. Assicurati di accettare solo caratteri di url validi (io rimango con i caratteri word PCRE) per il nome del sito. Tuttavia, un sistema di "convalida questa e-mail" sarebbe appropriato, per assicurarsi che il dichiarante controlli effettivamente l'indirizzo email fornito.
  2. Sembra buono. Mi piace Sha1 meglio di MD5, però.
  3. Fintanto che le sessioni sono sicure, è possibile memorizzare più del solo nome utente (che sarebbe una ricerca abbastanza costosa per SQL per ogni richiesta di pagina - andare avanti e memorizzare il proprio PK).
  4. sembra buono, ma deve essere regolato per i miei commenti a # 3

Per assicurarsi che si sta gestendo la sicurezza della sessione correttamente, controllare the guide on PHPSec.

3
  • Limitare la velocità sugli accessi. Registra ogni tentativo per un utente e bloccalo dopo tanti tentativi falliti. Mentre i tentativi falliti si bloccano, rendere il blocco sempre più lungo.

  • Aggiungere un sale nel codice che è statico e utilizzarlo in combinazione con il sale dal database. Quindi se db viene hackerato, non hanno ancora il sale dal codice. Questo sale non può/non deve cambiare.

  • Gli utenti possono recuperare le password/ripristinare i blocchi? dovrai raccogliere domande e risposte di sfida.

  • Quando gli utenti reimpostano la propria password, devono conoscere quella originale?

Se questo è un sito sicuro, o solo un sito che tiene traccia di qualcuno. Conosco i siti che puoi trasferire i cookie da una macchina all'altra per accedere. Ti ricorda sempre, ma è solo un forum, quindi il potenziale di problemi è basso.

Perché caricare il codice e il database? Una volta che il tuo database è stato violato il tuo sito è brusco. Tuttavia, vedere gli utenti tendono ad usare la stessa password su molti siti, non ha senso aiutare a violare la proprietà di tutti. Se ottengono il tuo codice anche allora succede il vero avvitamento, ma lascia alzare il maggior numero di barriere che possiamo.

La sicurezza attraverso l'oscurità è stupida, ma molti livelli di sicurezza possono essere d'aiuto.

Per quanto riguarda l'inserimento del nome utente nella sessione Hash il nome utente, l'URL e un valore salt. Memorizzalo nel database e nella sessione. usalo come autenticazione, se non è valido scaricalo al login. non possono copiare il cookie su un altro sito, non espongono il loro nome utente tanto quanto elimina una query.

È anche possibile rigenerare quel valore salato ogni X pagine e memorizzarlo nella sessione per espellerlo e renderlo meno utile nel tempo. Quindi memorizzerai due sali nel tuo database. Uno per la password, uno per il valore della sessione di autenticazione.

+0

, anche se quello che dici nel tuo secondo proiettile è vero, una volta che il database è stato violato il gioco è piuttosto scadente, no? = P –

+0

Retrive password - una nuova password viene inviata all'indirizzo degli utenti ed è costretta a cambiare all'accesso successivo Gli utenti devono sapere il p/w esistente per cambiare –

+0

Aggiornato il mio pensiero sulla salatura del codice – MrChrister

0

Se ottengo il flusso corretto, se conosco il nome utente e il nome del sito, andare al nome del sito e fornire un cookie con il nome utente (poiché le sessioni, dopo tutto, vengono salvate come cookie), sono in - nessuna password necessaria? Non è un difetto?

+0

Ho visto questo, e per quanto posso vedere, l'ID di sessione è memorizzato come cookie, ma nessuna delle variabili in esso? –

+0

Il tuo 4 ° punto diceva che "Su ogni richiesta, utilizzo il nome utente memorizzato nel sessio n "(che può essere falsificato) e quindi confrontarlo con il nome del sito nell'url stesso. Quindi se li forgio entrambi - Sono dentro – Liorsion

1

La mia preoccupazione è che qualcuno possa scrivere alla sessione e quindi essere in grado di accedere alle pagine delle persone se conoscono il nome utente con cui si sono iscritti? Come faresti a prevenire questo?

Non sono sicuro di cosa intendi. Come potrebbe qualcuno "scrivere alla sessione"? La sessione è [di solito] un file memorizzato sul server che il client non può visualizzare o modificare.

Se si è preoccupati per il dirottamento di sessione (ovvero la fissazione), è necessario abilitare SSL e disabilitare gli ID di sessione nella stringa dell'URL. (Vedi php.ini del session.use_only_cookies)

4 - Su ogni richiesta, io uso il nome utente memorizzato nella sessione per interrogare il database e leggere il nome del sito associato a questo utente. Poi lo paragono al nome del sito nell'URL stesso, e se corrispondono corrispondono a una variabile accessibile al resto o allo script (non una variabile globale, è solo leggibile dal mio controller che decide se un utente può vedere una pagina particolare) se i due nomi dei siti non corrispondono, l'utente viene reindirizzato al login

Questo suona come la più grande preoccupazione. Come appare il nome del sito? Quanto esattamente lo stai abbinando all'URL? Con una regex?

Alcuni ulteriori dettagli su questo aspetto sarebbero positivi, perché se il controllo degli accessi è difettoso, la qualità dell'autenticazione non è eccessiva.

Problemi correlati