Newsgroup: it.comp.www.php
Titolo: Evitare di inviare via POST i dati di login in chiaro

Salve a tutti. Sono nuovo in questo gruppo.
Sto realizzando un cms che necessita di una procedura di autenticazione in avvio, mediante userid e password. Il tutto su area intranet.
Non posso utilizzare il protocollo https.
Per quanto riguarda le password intendo memorizzare nel db l'hash sha512 delle stesse e basare l'autenticazione sul confronto dei relativi valori di hash.
Il mio dubbio è questo: per ragioni di sicurezza sarebbe meglio strutturare il form con del codice javascript, in modo tale che l'hashing della password inserita dall'utente avvenga lato client, e venga quindi inviato alla pagina di autenticazione (php), con metodo post, soltanto il valore hash? Oppure si può lasciare viaggiare in chiaro il valore del campo input relativo alla password, affidando infine a php il compito di generare l'hash per il confronto con quello contenuto nel db?
Con il primo sistema, però, renderei visibile ad un utente accorto l'algoritmo di hashing utilizzato (basterebbe aprire e leggere il file javascript); con il secondo sistema dovrei far circolare la password in chiaro fra il client ed il server, con tutti i rischi che ciò potrebbe comportare.
Mi interessa capire bene le implicazioni ed i rischi per la sicurezza conseguenti all'uno ed all'altro sistema, a prescindere da altre questioni come l'uso dei salt o hmac.

 come l'uso dei salt o hmac.
 
Utilizza HTTPS.
Oppure solo HTTP, fai viaggiare solo cose in chiaro, e sposta il problema
a chi/come si può connettere alla intranet: se il sistema gira in un ufficio,
su tre PC più un server, collegati in LAN, e senza accesso a internet o a
periferiche esterne (il che, considerando l'uso di chiavette USB, è difficile
da garantire), allora non c'è nessun problema.
 
Ciao!

>Con il primo sistema, però, renderei visibile ad un utente accorto l'algoritmo di hashing utilizzato (basterebbe aprire e leggere il file javascript); con il secondo sistema dovrei far circolare la password in chiaro fra il client ed il server, con tutti i rischi che ciò potrebbe comportare. 
 
Anche vedendo e modificando lo script non ottiene nessun vantaggio, forse il limite è che non puoi usare il sale per le password nel db.

 comportare.
 
Farlo circolare in chiaro o crittato è la stessa cosa.
Se qualcuno intercetta quel valore, non deve fare altro che rimandarlo 
uguale al tuo server, e lui lo autentica.
 
Tanto vale dire agli utenti di usare password non banali (che è quello che 
dovrebbero fare).
 
L'unico modo è https, ma visto che hai detto che non puoi usarlo, non 
farti troppe pare mentali e manda la password in chiaro.
 
Bye.

Il mio dubbio è questo: per ragioni di sicurezza sarebbe meglio strutturare il form con del codice javascript, in modo tale che l'hashing della password inserita dall'utente avvenga lato client, e venga quindi inviato alla pagina di autenticazione (php), con metodo post, soltanto il valore hash? Oppure si può lasciare viaggiare in
chiaro il valore del campo input relativo alla password, affidando infine a php il compito di generare l'hash per il confronto con quello contenuto nel db?
 
Tecnicamente non c'è differenza. Per essere autenticato tu devi mandare un
blob di bit. Se uno lo intercetta può rimandarlo uguale, e che sia la pass
in chiaro o uno SHA-65536 non cambierà le cose.
 
C'e' la differenza che la password dell'utente (che magari usa anche per i
rimanenti siti) non viene catturata mentre viaggia.
 
Per evitare i replay attack, puoi usare una cosa javascript che fa così:
 
	- il server invia una challenge veramente random C
	- il client legge dall'utente la password P
	- effettua uno SHA-512 (in javascript) ottenendo H
	- effettua uno SHA-512 di H concatenato C ottenendo K
	- invia K
 
	- il server riceve K, conosce SHA512(P), verifica se
	  SHA512(SHA512(P) concatenato H) è davvero K
 
Questo sistema è vulnerabile a una cattura del database. Però:
 
a) La password originaria, magari usata da altri siti, non è rivelata
b) Se un attaccante mette le mani sul DB, è probabile che abbia accesso a
   tutto il server, e modificare il codice per introdurre una backdoor in
   grado di bypassare del tutto l'autenticazione è relativamente facile.
 
Leonardo
 
-- 
 
Now suppose -just suppose- I could show you a way to
manufacture a wall that would do the same job... but
was only one inch thick.

 uguale al tuo server, e lui lo autentica.
 
Do per scontato troppe cose. Se al login passi il sale (casuale per ogni richiesta di login) a quel punto vedere il traffico iniziale non ti serve, certo che criptare la password non equivale a proteggere il traffico, ma questo era chiaro fin da subito e vedere lo script non aiuta.

 
 
Questo sistema è vulnerabile a un MITM, nel passo 5.
 
Ciao!

         - invia K ?
 
Spiegati che mi interessa


Se sei nel mezzo tra client e server, leggi e fai passare tutto fino a quel
punto. Una volta intercettato K, mandi al client un 503 e la K al server
la mandi te.
 
Ciao!


Se il client usa te come proxy, ma se avete ip diversi...


Nel tuo algoritmo non c'era nessun controllo sull'IP :)
 
Ciao!


Quindi sei d'accordo nel considerare il sistema come robusto

 Quindi sei d'accordo nel considerare il sistema come robusto
 
No, visto che il problema del MITM rimane pari pari. Se il server controlla
anche l'IP, si fa relay fin dal primo messaggio.
 
L'unico modo per avere un sistema "robusto" per questa strada sarebbe
reimplementarsi tutto il sistema di TLS sopra HTTP, il che è semplicemente
follia! :)
 
Ciao!


Come già avevo accennato: il proxy. Però devi modificare la configurazione dei client, a quel punto con un bel keylogger fai prima e questo non è propriamente un mtm che legge il traffico. O del dns se lo usano. Senza considerare che l'utente non può accedere, quindi ben visibile, e poi lasci tracce nella configurazione del proxy che indica il server malevolo. Ed è mono uso.
 
Se non potessi usare ssl questo è il sistema che molto probabilmente adotterei.
 
Mentre te preferiresti andare scoperto, senza accorgersi di nulla violabile com'è con un banale sniffer.

 com'è con un banale sniffer.
 
Come sopra, chi sa usare uno sniffer sa anche fare spoofing.
 
Ciao!


Contribuisco con i miei 2 cent...
 
ma se la connessione è in chiaro, a quel punto il server ti assegnerà
un cookie di sessione che può essere tranquillamente utilizzato da
qualcun'altro.
 
L'uso è ovviamente valido durante la sessione di lavoro dell'utente
autenticato, ma esso deve pure ricordarsi di effettuare la 
disconnessione volontariamente, se no, sempre il nostro hacker malevolo
può fare ciò che vuole all'infinito.
 
Dovresti aggiungere qualche controllo in più non solo in fase di login,
ma questo dipende anche dall'implementazione specifica.
 
Ciao!
 

Infatti, anche se non è l'equivalente di avere la password funziona in assenza di lss.
 
Se però come già detto il server memorizza l'ip del client avere il cookie non ti avvantaggia.

 sinceramente non li capisco.
 
Boh? Avrà un server http leggero. Di sicuro è che ti difendi male senza ssl.
 
 

 Di sicuro è che ti difendi male senza ssl.
 
Infatti, questo è il succo di tutto il discorso
 
Ciao!

Questo sistema è vulnerabile a un MITM, nel passo 5.
 
Uhm, non ho capito. La nostra Eve può mettere le mani su C e su
SHA(H|C)... o non ho capito un apascio?
 
In che modo riesce a ri-autenticarsi sul server? La volta dopo,
ricevera' un nuovo C' e non sarà in grado di generare SHA(H|C')
perché non ha H e SHA è supposto non invertibile.
 
Certamente può fare session hijacking, ma questo può farlo dato
che è su HTTP.
 
L'unico modo per impedirlo sarebbe usare una funzione simile su
ogni pacchetto trasferito fra client e server, usando magari un
algoritmo P/P per negoziare una chiave simmetrica di cifratura.
 
E avremmo reinventato HTTPS :-)
 
Cosa che è fattibile, visto che è stata fatta:
 
 
https://github.com/digitalbazaar/forge
 


 
 
... ecco, queste sono le cose che mi mettono paura.
Immagino sia ideato per girare sopra nodejs e non su un client ma, in ogni
caso, mamma mia! :)
 
Ciao!

caso, mamma mia! :)
 
Non so, non ho avuto il coraggio di guardare :-D


 Infatti, questo è il succo di tutto il discorso
 
Meno male che qui siam d'accordo!! :)
 
Visto l'interesse di Marco - che nel frattempo son convinto abbia imparato a farsi i certificati autofirmati - direi che potremmo anche fermarci. Sempre se sei d'accordo :p


 
Sìsì, anche perché alla fine stiamo dicendo la stessa cosa :)
 
Ciao!

Vi ringrazio tutti per le preziose informazioni.
Il motivo per cui non posso usare HTTPS è che gli script PHP dovranno stare su un server virtuale con EasyPhp e su piattaforma Windows. Ho il mal di testa al solo pensiero di mettere mano al modulo di Apache per implementare SSL. La dimensione del sistema in progettazione (una ventina di pc) e la tipologia dei dati che verranno trattati (nè dati sensibili nè giudiziari) non giustificano a mio parere un simile impegno.
Oltre all'autenticazione mediante userid e password, sfrutterò PHP per filtrare i client in base al loro IP privato. Ovviamente utilizzerò le sessioni (solo su cookie), che verranno sempre rigenerate ad ogni caricamento di pagina.
Quella di inviare al client un challenge random (a proposito: la funzione rand() di PHP è veramente random???) mi pare una soluzione di compromesso accettabile: pensavo di salvarne il valore sulla variabile  $_SESSION["challenge"] e contemporaneamente creare un campo input hidden che la contenga, in modo tale da permettere a javascript di recuperarlo per generarne l'hash e concatenarlo a quello della password. Secondo voi potrebbe andare od è preferibile inviarla su cookie anzichè su input hidden?

 hidden?
 
Se hai problemi di MITM la sicurezza è zero. Tutto quello che invii al 
client, inclusi il challenge e lo script JS che deve calcolarlo, passa per 
la macchina del MITM, che, dopo aver analizzato il traffico la prima 
volta, ci mette poco a mandare al client una funzione tipo function 
password(psw) { return pwd; } al posto della tua, per poi usare il tuo 
algoritmo sul suo "proxy non trasparente", con doppio vantaggio: raccoglie 
le password in chiaro e diventa invisibile ai tuoi occhi.
 
Sono pronto a scommettere che impieghi meno a imparare come configurare 
SSL su Windows che a studiare un algoritmo anche solo vagamente sicuro.
 
Bye.
 

Scusate per l'OT, ho capito che è inutile tentare di migliorare lo script rimanendo in HTTP. Per favore qualcuno mi sa suggerire la configurazione del file httpd.conf di Apache (vers. 2.4) per SSL? 
Ho già effettuato diverse prove, messo in Listen la porta 443 e decommentato la riga #LoadModule ssl_module modules/mod_ssl.so, ma Apache non si riavvia. 
Poi ho anche decommentato la riga #Include conf/extra/httpd-ssl.conf ed aggiunto, prima della riga #<VirtualHost _default_: 443>: 
 
SSLMutex predefinita 
 SSLRandomSeed avvio builtin 
 SSLSessionCache  none 
< VirtualHost 
127.0.0.1
: 443 > 
     SSLEngine  On 
    SSLCertificateFile conf/ssl/site.cert 
     SSLCertificateKeyFile conf/ssl/site.key 
</ VirtualHost> 
 
ma ancora niente da fare... Apache non si riavvia... 
Qualcuno mi sa dare una mano? Grazie!!!