Vi sono gravi problemi di invio del login e della password dell'utente con ogni richiesta HTTPS?

7

A causa di determinati requisiti / vincoli, mi chiedo se inviare login utente e password ad ogni richiesta.

Questo in qualche modo non mi sembra molto buono, anche se penso che per il mio caso particolare potrebbe avere un senso: ridurrebbe il numero di richieste HTTP, ridurrà la latenza e semplificherà il codice di frontend.

Ecco la situazione:

  • Il traffico verso il server proviene da un'app mobile
  • Tutto il traffico passa attraverso HTTPS
  • Manteniamo le credenziali dell'utente crittografate nella memoria del dispositivo per registrare automaticamente gli utenti su ogni avvio di app
  • Il timeout della sessione lato server è molto basso (pochi minuti) ed è fuori dal mio controllo
  • Il DB è fuori dal mio controllo; Non posso aggiungere nulla al DB facilmente e rapidamente (sarebbe una bella sfida ottenere un campo DB se, ad esempio, volessi un token di sessione di lunga durata)
  • Il traffico nell'app si verifica di solito nei batch
  • Il tipico batch di traffico all'interno del timeout della sessione è costituito da poche richieste HTTPS
  • Poiché il traffico proviene dall'app mobile, l'invio di richieste "keep alive alive" non è sempre possibile; se l'utente uccide un'applicazione e rilancia pochi minuti dopo (o riduce al minimo per alcuni minuti), non c'è possibilità di mantenere la sessione, e ho bisogno di relogin l'utente.

Quindi, lo schema di traffico tipico attualmente è:

#USER OPENS THE APP
POST /autologin    -> response: [ok, here's the new sessionid]|[auth failure, maybe the password changed since]
#SUPPOSING AUTH WAS OK; USER BROWSES AROUND THE APP
POST /someAction1
POST /someAction2
POST /someAction3
#USER IDLE FOR A FEW MINUTES
POST /keepSession
...
#USER MINIMIZES THE APP
#USER RELAUNCHES THE APP, MAYBE SEVERAL MINUTES LATER, MAYBE NEXT DAY
POST /someAction4  -> response: sessionTimeout
POST /autologin    -> response: [ok, here's the new sessionid]|[auth failure, maybe the password changed since]
#SUPPOSING AUTH WAS OK; USER BROWSES AROUND THE APP
POST /someAction4
...

Ad ogni modo, in media, devo inviare la richiesta di accesso abbastanza spesso una volta scaduta la sessione; percentuale significativa di richieste sono richieste di accesso.

Se invio login e password in ogni richiesta, posso

  • elimina le richieste di /autologin all'avvio
  • sbarazzarsi delle richieste di /keepSession ogni pochi minuti mentre l'utente è attivo
  • elimina /action - > /autologin - > /action combo in caso di sessione scaduta; giù dalla 3 richiesta a solo 1

Potrei sempre inviare sia il sessionid che la password di login +, quindi su sessionid per il riutilizzo del backend se ancora valido, altrimenti creare una nuova sessione usando login e password, e fare quello che volevo all'interno della stessa chiamata HTTP, senza la necessità per giocare a ping-pong tra frontend e backend.

Per riassumere, dal mio punto di vista:

Contro:

  • Dovrei occuparmi del backend per non accidentalmente registrare le credenziali dell'utente in più gestori di richieste, non solo in uno (gestore di accesso)
  • potrebbe aumentare il numero di richieste con login e passare in carico utile forse di un fattore di N = ~ 4,

Pro:

  • il numero complessivo di richieste HTTP effettuate dal server è diminuito del 20% circa
  • nessuna necessità di logica di frontend per mantenere la sessione utente; spara ogni richiesta con le credenziali. Se fallisce a causa di un problema di autenticazione, disconnetti l'utente.

Sapendo che il traffico è crittografato con HTTPS, ci sono dei lati negativi severi nel mio post-accesso-pass-and-pass sempre in corso?

    
posta jakub.g 24.09.2015 - 14:53
fonte

3 risposte

4

A meno che non si costruisca il proprio meccanismo di sicurezza (che in genere è sconsigliato) ci si affida alla sicurezza di SSL per proteggere l'autenticazione. Generalmente questo viene fatto con una qualche forma di token che se catturato può essere usato per replicare il login. Quindi un utente malintenzionato in grado di interrompere SSL può anche acquisire la chiave di sessione e assumere la sessione esistente.

Ci sono un paio di differenze tra una chiave di sessione e un nome utente / password. Il primo è che alla fine la chiave di sessione scadrà, mentre un nome utente / password sopravvive per un tempo molto più lungo. Generalmente questo è considerato un vantaggio di sicurezza minore perché un utente malintenzionato deve semplicemente essere tempestivo nell'usare la chiave di sessione acquisita. Una differenza più grande è che la password può essere utilizzata per autenticare di nuovo quando viene intrapresa un'azione critica, come il trasferimento di denaro nell'account o la modifica della password. In questo caso non è utile catturare solo la sessione, poiché l'utente malintenzionato dovrebbe acquisire anche la password.

Anche in uno scenario protetto con chiave di sessione, il nome utente / password è ancora inviato una volta per sessione. Se l'utente malintenzionato può interrompere completamente la sessione SSL, può acquisire lo scambio iniziale nome utente / password.

Ora, interrompere SSL non deve significare un'interruzione completa. Esistono potenziali scenari di interruzione parziale in cui un'interruzione di SSL potrebbe essere più vulnerabile all'invio del nome utente / password molte volte rispetto a una sola volta per sessione.

La linea di fondo è che l'uso di una chiave di sessione è un po 'più sicuro (se fatto correttamente) rispetto all'invio di username / password ogni volta. Devi bilanciare questa sicurezza con il resto delle tue esigenze di backend. Ma capisci che, qualunque cosa tu stia facendo, stai ancora facendo affidamento sulla sicurezza di SSL.

    
risposta data 24.09.2015 - 18:18
fonte
0

Oltre alla risposta di @Steve Sether, la maggior parte dei browser moderni è in grado di rilevare attacchi MITM che possono essere utilizzati per compromettere la chiave di sessione controllando i certificati del server.

Se utilizzi TLS e consenti solo certificati validi, l'approccio descritto non influisce sulla sicurezza. Inoltre, la chiave di sessione e la sessione Web sono due cose diverse, il che significa che la durata della chiave di sessione è indipendente dalla sessione dell'applicazione Web creata tra l'app e il server.

La chiave di sessione garantisce la sicurezza in avanti, nel senso che compromettere la chiave corrente non è utile per decifrare le sessioni future o precedenti. Pertanto, è possibile reinizializzare la sessione TLS alla velocità media di scadenza della sessione Web e inviare il nome utente / password a metà della tariffa per la sicurezza.

    
risposta data 25.09.2015 - 15:12
fonte
-2

Mi sembra una cattiva idea (il seguito è solo la mia opinione)

Se si sta inviando il nome utente / password a ogni richiesta HTTP, è possibile che alcuni bit nei dati crittografati non vengano modificati. quindi, presumo che se vengono richieste abbastanza richieste HTTPS (a migliaia o anche a milioni), allora c'è una possibilità per un utente malintenzionato di impersonare un cliente.

Se si confronta una richiesta HEAD HTTP non crittografata inviata da un client con un'altra inviata dallo stesso Client allo stesso server, non è affatto diversa. quindi, se un utente malintenzionato può catturarne una quantità sufficiente nel flusso HTTPS, anche se crittografato, l'utente malintenzionato può ancora indovinare gli altri bit e creare il proprio pacchetto per impersonare il client.

Questo è anche uno dei motivi per cui è necessario scadere i cookie dopo un periodo di tempo, in modo che sia difficile per un utente malintenzionato raccogliere un numero sufficiente di richieste simili.

    
risposta data 24.09.2015 - 17:32
fonte

Leggi altre domande sui tag