Cleartext password in HTML

7

C'è qualche problema con l'output della password di un utente in HTML in un campo nascosto (vedi use case qui sotto prima di flaming xD)?

Il caso d'uso è un modulo di registrazione con due passaggi. L'utente inserisce la password nel primo passaggio, ma per evitare di memorizzare i valori del campo da qualche parte nel server, l'applicazione invia i valori al client nell'HTML come campi nascosti. Questi campi vengono nuovamente inviati sul server quando il client invia il secondo passaggio della registrazione. In questo modo, il server riceve tutti i valori contemporaneamente e la logica è più semplice.

In pratica, basta dividere la richiesta di registrazione in due richieste in cui la seconda è l'unica che conta. Il problema è che non mi sento troppo a mio agio se la password è presente nell'HTML, ma non riesco a evocare una ragione sufficiente perché ciò sia sbagliato ...

Modifica

Solo per rendere le cose un po 'più difficili, supponiamo che HTTPS sia usato ovunque, e X-Frame-Options sia usato per prevenire il Clickjacking. Qualcuno può pensare a qualsiasi attacco che non è stato menzionato in precedenza che funzioni con questa configurazione?

    
posta Francisco Vieira 03.05.2013 - 19:49
fonte

6 risposte

12

Vedo alcuni motivi per non farlo:

  • Il browser client potrebbe (e probabilmente lo farà) memorizzare nella cache la pagina HTML ricevuta in qualche file sul disco locale. Di solito non è una buona idea avere le password "così come sono" nei file sul disco.

  • Poiché si memorizzano i dati sul lato client (nell'HTML), è necessario pensare a cosa succede quando il client non collabora, cioè restituisce qualcosa di diverso da ciò che il server ha scritto nell'HTML. A seconda del contesto, questo può o non può essere un problema, ma almeno alcuni pensano che deve essere fatto al riguardo.

Il modo generico e sicuro per fare questo genere di cose è di restituire al client un blob crittografato, che contiene i dati di stato che si desidera memorizzare sul client. Il blob deve utilizzare sia la crittografia sia un MAC per proteggere dalle alterazioni dei client dannosi. Dove hai effettivamente messo quel blob non è molto importante; puoi metterlo in un campo nascosto nell'HTML o in un cookie - non avrà molta importanza dato che, attraverso la crittografia e il MAC, non ti fidi effettivamente della macchina client per nulla.

    
risposta data 03.05.2013 - 19:58
fonte
4

Il tuo caso d'uso non è contestualmente diverso dalla visualizzazione di un semplice modulo a pagina singola che l'utente non è riuscito a compilare correttamente, e per comodità il tuo codice server ha riempito nuovamente i campi che l'utente ha compilato correttamente. Vediamo molti di questi esempi sul web. L'unica differenza è che utilizzi due pagine per un set completo di dati utente obbligatori (e facoltativi) che stai raccogliendo. Potresti anche usare venti di questi passaggi, non ha importanza dal punto di vista della sicurezza (potrebbe essere così per gli utenti, ma è diverso), a patto che:

  • Ti sei occupato di TLS
  • Tratti tutti gli input dell'utente, indipendentemente dalla pagina da cui provengono, nel complesso
  • Non esporre inutilmente le password di testo in chiaro nella cache dell'utente finale

Hai menzionato nei commenti che questo sarà su HTTPS, quindi il primo è curato. Entrambi gli altri due sono completamente gestibili:

Il codice lato server che verifica l'input dell'utente dovrà essere scritto in modo tale da adattarsi a più pagine di moduli utente, ma anche controllare i vincoli di input in modo incrementale, vale a dire che ogni nuova pagina controllerà tutti i dati inseriti su quelli precedenti , fino alla pagina in cui l'utente è attualmente attivo. Accettate anche tutti questi moduli separati nel loro insieme, il che significa che un errore su uno ripristina la visualizzazione di quel particolare stadio di input dell'utente finale , rilascia tutti i dati del modulo successivo e visualizza i relativi errore per quella pagina (o fase, passaggio, comunque tu vuoi chiamarlo). La parte importante è che accetti tutti gli input dell'utente solo dopo che tutti i dati sono stati verificati in base alle tue esigenze in tutte le fasi di inserimento del modulo. Solo così puoi tranquillamente scrivere qualsiasi cosa nel tuo database - cioè tutti i requisiti sono stati soddisfatti.

Perché non inviare le password degli utenti finali in cancella testo non è un problema? Perché l'hai già inviato almeno una volta nella direzione opposta al server. Se questo non dovrebbe essere un problema, rimandarlo indietro usando lo stesso TLS non dovrebbe altrettanto bene. Non dovrebbe , perché dovrai ancora considerare questi dati memorizzati nella cache dell'utente dal browser, come ha sottolineato @ThomasPornin. Ciò è tuttavia controllabile con i tag di intestazione della cache del browser, sia come tag HTML, sia nelle intestazioni di risposta del server HTTP. Non entrerò nei dettagli su come ottenerlo, in quanto è un argomento ben trattato e ha anche molte discussioni su StackOverflow. Il principale punto d'appoggio è che se il tuo front-end è già stato aperto con una iniezione XSS, nulla impedisce a questa iniezione di raccogliere i dati degli utenti finali sul modulo di invio dallo stesso campo di input, quindi inviarlo di nuovo non lo espone realmente più per questi tipi di attacchi, ma la cache del client dovrebbe essere ancora considerata per impedire l'esposizione di password di testo in chiaro ad altri tipi di attacco.

Altri hanno anche suggerito di utilizzare AJAX per parti dei dati del modulo. Se è vero che può aiutare con l'input dell'utente, guidando gli utenti mentre vanno con feedback, non dovresti mai accettare solo i dati parziali come qualcosa su cui contare in seguito, quando completi una fase di invio del modulo o quando completi il processo nel suo insieme. Controllare la disponibilità del nome visualizzato o simile è perfetto, ma se è nel frattempo preso da un altro utente, non è certo il caso di fare affidamento su quella richiesta AJAX precedente per decidere, se l'utente corrente continua a usarlo.

    
risposta data 06.05.2013 - 18:58
fonte
3

Se non vuoi memorizzare la password sul server, perché stai facendo due passi per la creazione dell'utente? Se stai controllando solo la disponibilità del nome utente, perché non utilizzare il postback AJAX per inviare solo le informazioni che devono essere verificate e fare tutto in un unico modulo?

Anche se hai bisogno di rimandarlo, non vedo perché non possa essere mantenuto nella sessione dell'utente fintanto che il server non lo rimanda mai all'utente. È possibile eseguire immediatamente l'hash che verrà applicato quando lo si memorizza nel DB in modo che non venga conservato nulla che altrimenti non verrà conservato.

    
risposta data 03.05.2013 - 20:17
fonte
3

Inserendo la password di testo non crittografato (o qualsiasi dato sensibile) all'interno del codice sorgente o del DOM della pagina stai correndo un grosso rischio.

Ad esempio, solo una semplice vulnerabilità Cross-Site Scripting (XSS) rende banale la lettura di tale valore e lo invia ovunque l'autore dell'attacco desideri.

Inoltre, altre tecniche che coinvolgono il Clickjacking sono usate per leggere il contenuto da fonti arbitrarie di iframe, come quella che contiene la tua password.

Memorizzare dati sensibili che non ha bisogno di essere lì (cioè l'utente non ha bisogno di leggerlo) all'interno della fonte delle pagine web non è mai un buon idea.

    
risposta data 04.05.2013 - 01:24
fonte
3

Se, per qualsiasi motivo, la password ha bisogno di per essere rispedita e 'semplicemente siediti' sul secondo perché non codificarla sul lato server con una stringa salt ie myencode ($ salt, $ pass ); invia il passaggio codificato e quando viene restituito decodifica cioè mydecode ($ pass2); Questo sembrerebbe il percorso più semplice che manterrebbe comunque un livello di sicurezza accettabile.

O, un po 'più complicato ma per citare un poster precedente "questo urla ajax"

    
risposta data 04.05.2013 - 04:45
fonte
2

Sicuramente un problema. La trasmissione della password in qualsiasi modo di testo chiaro apre molti problemi di sicurezza.

Uno in particolare che ti viene in mente, sei sicuro che la rete dell'utente non venga sniffata o orecchiata? Consentendo la password di testo non crittografato (in generale), chiunque possa intercettare la rete dell'utente non avrà pieno accesso alla propria password. Questo crea altri problemi perché molti utenti usano la stessa password su più siti web. Hai appena autorizzato che il tuo utente diventasse una vittima con una codifica scadente.

Una nota a margine, perché non spostare semplicemente la parte della password nella seconda fase della registrazione ed essere l'ultimo passaggio? In questo modo è (si spera) trasmesso in modo criptato e sicuro.

    
risposta data 03.05.2013 - 20:57
fonte

Leggi altre domande sui tag