2010-05-04 12 views
7

Ho un sito Web di annunci, in cui tutti possono pubblicare annunci dei loro prodotti.Verifica della password; È questo modo di farlo al sicuro?

Per ciascun classificato, l'utente deve immettere una password (in modo che possano eliminare il classificatore ogni volta che lo desiderano).

Quindi, in pratica, quando qualcuno vuole eliminare un annuncio, fa clic sul classificatore, fa clic sul pulsante Elimina e inserisce il pass.

Io uso MySql come database.

Io uso questo codice in fondo:

if ($pass==$row['poster_password']) 

dove row [poster_password] è prelevato dalla MySql ...

Cosa ne pensi? Grazie

+18

Si prega di tel Io non hai salvato la loro vera password in MySQL ... – animuson

+1

sì, ma hey, il sito web non è ancora online, in fase di sviluppo ... Sto solo iniziando sul fronte della sicurezza ora ... Come dovrebbe Lo salvo allora? –

+0

@animuson è così importante per il sito web di annunci? –

risposta

9

vedere questo: Secure hash and salt for PHP passwords

Hash la propria password (forse con un po 'di sale) sulla strada nel database. Memorizza la password hash nel database (NON la loro password effettiva). Quindi recuperare la loro password hash dal database e hash la loro password di input e confrontare le password con hash.

Alcuni pseudo codice zoppo:

password_hash = hash(password_cleartext) 
# store password_hash in database 

tardi:

input_password_hash = hash(input_password_cleartext) 
fetched_password_hash_from_db = fetch(db, password_hash) 
if (input_password_hash == fetched_password_hash_from_db) { 
    ... authenticated ... 
} 

Tanto per cominciare con php, provo: http://php.net/manual/en/function.sha1.php

+6

+1 per il primo a menzionare l'hashing. ** HASHING NON ​​È GENTE DI CRITICAZIONE ** - sono concetti completamente diversi * (non è uguale a un checksum, che non è necessariamente crittograficamente sicuro) *. Inoltre, ** MD5 è completamente guasto **, non usarlo. –

+2

+1 per aver menzionato che MD5 è rotto! – dlamotte

+0

Ok, allora l'hash è una funzione di php, immagino? Hai un esempio acutistico? –

0

È necessario eseguire l'hash della password in qualche modo e archiviare e confrontare utilizzando la versione con hash. Vedere questo link per maggiori informazioni:

http://phpsec.org/articles/2005/password-hashing.html

+0

E sì, non memorizzare la password effettiva OVUNQUE. – quoo

+1

Penso che la crittografia sia una parola ingannevole qui. È "hashing crittografico", non crittografia. La crittografia suona come la semplice crittografia della password contro l'hashing che non può essere "invertita". – dlamotte

+0

Le password devono essere sempre sottoposte a hash. La crittografia non dovrebbe mai essere utilizzata per le password. – rook

2

Non conservare la password effettiva nel database. Memorizza invece un checksum (MD5, SHA1, ecc.). Quando si desidera confrontare, eseguire un checksum del valore che l'utente invia e confronta i checksum.

In questo modo non si ha la password effettiva in memoria.

+0

... o memorizzati ovunque per quella materia. – Steven

+0

md4, md5, sha0 andsha1 sono funzioni hash rotte. Chiunque abbia una vulnerabilità avrà un -1, scusate le sue regole. sha256 dovrebbe essere usato. – rook

+1

Devi averlo in memoria quando lo controlli, a meno che tu non abbia hash sul lato client in javascript. Non è importante - se un malintenzionato può accedere alla memoria, avendo la password ci sarà l'ultima delle tue preoccupazioni. – Tgr

0

avrei crittografare la password prima di riporlo, decifrare quando recuperandolo in modo da poterlo confrontare con ciò che l'utente ha inserito in testo in chiaro (secondo il tuo codice di esempio sopra).

Inoltre, proteggersi da qualsiasi SQL injections, o qualcuno potrebbe vedere tutte le password (e altri dati) nel database.

+0

-1 la crittografia non dovrebbe mai essere utilizzata per le password. Questa è una chiara violazione di CWE-257 (http://cwe.mitre.org/data/definitions/257.html) Dovrebbe essere usata una funzione di digest del messaggio come sha256. Chiunque abbia una vulnerabilità ottiene un -1, questo è il regolamento. – rook

+0

-1 per The Rook per dire che la crittografia non dovrebbe mai essere utilizzata, quindi citare CWE-257 che dice "Usa la crittografia forte e non reversibile per proteggere le password memorizzate." –

0

Ciò implica che le password non vengano crittografate nelle password. Se questo è il caso, dovresti utilizzare una sorta di crittografia quando inserisci le password. Un modo per farlo è la funzione MD5 che blocca la password.

Quando si esegue l'inserto si farebbe

Insert into table(email, password, whatever) values('$email', md5($password), whatever) 

E quando si confrontano fareste

if (md5($pass) == $row['password']) 
+0

-1 md4, md5, sha0 andsha1 sono funzioni hash rotte. Chiunque abbia una vulnerabilità avrà un -1, scusate le sue regole. sha256 dovrebbe essere usato – rook

+0

Abbastanza corretto, potresti fornire una fonte? – Gazler

+0

Vedi [here] (http://www.google.com/url?sa=t&source=web&ct=res&cd=1&ved=0CAYQFjAA&url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi% 3D10.1.1.60.3776% 26rep% 3Drep1% 26type% 3Dpdf & ei = 5m3gS9zCLZO8Nuigsc8J & usg = AFQjCNGSF9GeeOlCrWlb4LKSRlYlLlT2-w): * "Il nostro algoritmo [...] ** ci consente di trovare collisioni MD5 complete in pochi minuti ** su un Pentium 4 3Ghz ". * Wang et al. ha anche fornito (circa cinque anni fa) un metodo che mostra come trovare collisioni MD4 usando carta e penna. SHA1 è stato rotto più recentemente, anche se non così male (non ci sono ancora collisioni note). –

1

Le migliori pratiche è quello di mantenere un salato sha1 hash nel database:

if (sha1($pass.$row['poster_salt'])==$row['poster_password']) 

(poster_salt è una stringa casuale generata e salvata quando l'utente sceglie la password.)

In questo modo, se un utente malintenzionato accede al database, non otterrà ancora le password degli utenti (che sono probabilmente utilizzate anche altrove - la maggior parte delle persone non si preoccupa di scegliere password diverse per siti diversi).

Inoltre, è necessario utilizzare la connessione protetta (HTTPS). E richiedono password sufficientemente forti.

(Almeno se si desidera una buona sicurezza, che potrebbe essere eccessivo in caso di un semplice elenco di annunci).

+0

md4, md5, sha0 e sha1 sono funzioni hash rotte. Chiunque abbia una vulnerabilità avrà un -1, scusate le sue regole. sha256 deve essere usato – rook

+0

+1 La migliore risposta finora. @The Rook: Sembra un po 'ingiusto, sha1 non è così rotto come gli altri tre (nessuna collisione è stata ancora trovata) –

+1

@BlueRaja puoi mostrarci un punto debole di MD5 usando una collisione per favore? –

4

Il tuo codice sembra sicuro, ma il tuo progetto potrebbe richiedere un po 'di lavoro.

SQL Injection

La parte pericolosa del codice è in memorizzare nulla nel database, o mostrando qualsiasi cosa per gli utenti, che vengono raccolte da parte dell'utente. Quindi, la parte che devi fare attenzione si verifica prima del tuo esempio. Assicurati di convalidare, filtrare e sfuggire tutti i dati che raccogli da parte dell'utente, inclusi la password e le informazioni sull'annuncio.

crittografia

Il vantaggio di memorizzare la password nel database è che si può permettere all'utente di recuperare la password tramite e-mail o altri mezzi se perdono esso.

Tuttavia, se lo fai memorizzare le password, è necessario memorizzare le cifrati, utilizzando una chiave segreta, in modo che se qualcuno è in grado di dirigere l'accesso in lettura al database, non possono leggere tutte le password in testo normale. Tuttavia, dovrai memorizzare la chiave segreta da qualche parte, e se qualcuno ottiene la tua chiave segreta e ha accesso al tuo database, avranno accesso a tutte le password.

valori hash (consigliato)

E 'migliori pratiche e più sicuro per memorizzare solo un modo valori di hash (SHA1 o SHA256) delle password nel database invece delle password attuali. In questo modo, non è possibile recuperare la password. I valori di hash sono intenzionalmente un modo eliminando alcuni dati.

Invece di recuperare la password originale, si hash la password che l'utente inserisce e confronta il valore di hash con il valore di hash memorizzato per vedere se corrisponde. Se l'utente perde la password in questo caso, invece di inviare la password via e-mail all'utente, si invia all'utente una nuova password generata casualmente.

Memorizzare solo il valore hash protegge ulteriormente i dati, poiché anche se l'utente ha accesso in lettura al database, i valori hash non offrono alcun vantaggio e non esiste una chiave segreta che sbloccherà tutti i valori hash.

Quando si hash le password, assicurarsi di utilizzare un valore salt casuale e memorizzare il sale per proteggere il tuo elenco di hash contro gli attacchi arcobaleno.

Sommario

a volte non si arriva a scegliere la password. A volte la password proviene da un altro sistema, quindi non sempre è possibile scegliere, e talvolta i tuoi superiori (forse anche gli utenti) richiederanno di essere in grado di recuperare le password, tuttavia, quando possibile, dovresti scegliere l'opzione più sicura .

Si noti che tutta questa attività di crittografia e valore hash protegge solo parzialmente il server da persone che sono in grado di ottenere accesso in sola lettura ai dati. A volte, ottenere i tuoi dati è sufficiente per un premio, quindi se l'utente può leggere l'hash della password, può leggere i numeri della tua carta di credito?

È necessario proteggere il database. Hai una password sicura sul tuo sistema di database? Autorizzi solo l'accesso locale ai tuoi dati? Hai creato un utente del database con i privilegi minimi da utilizzare nella tua applicazione? Ti stai proteggendo adeguatamente dagli attacchi di SQL injection e scripting?

Se qualcuno ha letto e scrive l'accesso ai dati, l'intera password aziendale diventa discutibile.

0

il mio suggerimento è il seguente

tabella utenti hanno due colonne, una denominata "password" e l'altro "sale"

$password = 'youruserpassword in plain text'; 
$salt = bin2hex(openssl_random_pseudo_bytes(32)); 
$passtostore = hash_hmac('sha384', $password, $salt); 
insert into users(password, salt) values($passtostore, $salt); 

Poi, per verificare se l'utente ha inserito la password corretta. ..

retrive sia la password e il sale dal database e

if(hash_hmac('sha384',$userpass, $row['salt']) === $row['password']) { 
// is valid 
} 
Problemi correlati