Perché il mio cliente non dovrebbe semplicemente inviare il nome utente e la password dell'utente ad ogni richiesta?

2

Ho un server PHP e un client Android / iOS, e SSL è usato per tutte le comunicazioni.

Il server PHP è un'API JSON con 2 funzioni pubbliche (registro, accesso) e molte funzioni private (che richiedono all'utente di "accedere").

Ho avuto alcune iterazioni e questo è il metodo corrente per diventare "loggato":

  1. POST utente una richiesta di accesso al server con nome utente e password.
  2. Il server tenta di autenticare il nome utente e la password con ciò che è memorizzato nel database (password_hash () viene utilizzato quando si memorizza la password, password_verify () viene utilizzato quando si tenta di autenticare, i dati di input sono convalidati e disinfettati ecc.). / li>
  3. Se il nome utente e la password sono autenticati, l'utente viene fornito con una JWT che scadrà dopo 1 minuto.
  4. Il JWT contiene: tempo di scadenza, nome utente e tipo di utente.

Tutte le funzioni private richiedono un JWT valido, non scaduto. 1 funzione privata è disponibile per richiedere un nuovo JWT. Preferisco questo modo di mantenere la sessione perché fornisce una sorta di heartbeat (il server sa entro 1 minuto che il client diventa inattivo).

Ho implementato il sistema in questo modo in modo che l'utente debba solo inviare il proprio nome utente e password una volta, in modo che il server debba solo eseguire 1 ricerca del database per autenticare l'utente all'inizio della propria sessione.

La mia domanda è: autenticarsi una sola volta e mantenere una sessione (che io faccia in questo modo o in un altro modo) più sicuro che inviare username e password ad ogni richiesta e autenticarsi ogni volta?

    
posta 27.04.2018 - 16:36
fonte

3 risposte

3

Se hai sempre attivato HTTPS, non devi preoccuparti della perdita di password durante le interazioni tra l'utente e l'endpoint dell'API. HTTPS lo proteggerà durante il transito sul login, in quanto proteggerà la password ad ogni richiesta.

Non sei più sicuro o meno sicuro inviando informazioni di accesso su ogni richiesta, ma stai creando un carico non necessario sul server delle applicazioni. Un sacco di carico.

Le password sono fatte per essere difficili da decifrare. L'algoritmo di hashing si aspetta che qualcuno cerchi di violare le password offline, quindi impiegano più pass per rallentare il processo di hashing. Se l'applicazione deve cancellare ogni password per ogni utente per ogni interazione, si sta facendo un duro lavoro al server delle applicazioni.

Quindi, continua con i token. Non dal punto di vista della sicurezza, ma dal punto di vista delle prestazioni. I token sono per questo, per garantire che l'utente sia autenticato, a costo di una lettura di file o di una ricerca nel database.

    
risposta data 27.04.2018 - 21:12
fonte
4

Se chiedi all'utente di immettere nuovamente un nome utente e una password ogni volta che l'applicazione deve effettuare una chiamata API, avranno un brutto momento e smetteranno di usarlo. Soprattutto se si verifica una situazione in cui una singola "azione" dalla loro prospettiva dà il via a più chiamate API che richiederebbero l'autenticazione separatamente. Questo non è fattibile. Questo non è l'unico modo in cui "

L'alternativa è avere il nome utente e la password dell'utente memorizzati sul loro dispositivo in modo che l'applicazione non debba richiedere per inviare la richiesta. L'utente non può dire la differenza tra l'applicazione che detiene un token arbitrario che consente l'accesso rispetto al nome utente + password che consente l'accesso, quindi va bene. Sfortunatamente, ci sono anche alcuni difetti, e questi difetti sono più rilevanti per la sicurezza.

Innanzitutto, a meno che l'applicazione non faccia uso di crittografia interna, il nome utente e la password finiscono effettivamente memorizzati uno accanto all'altro in chiaro. Anche se esiste una crittografia, la chiave di crittografia deve essere memorizzata quasi in prossimità di ciò che sta crittografando, il che non è molto meglio. Non posso dire con precisione quanta vulnerabilità sia, e un token rischia di essere altrettanto vulnerabile, ma un attaccante che si impadronisce di un singolo token è probabilmente meno dannoso di uno che ottiene il nome utente e la password completi.

In secondo luogo, come sapete, i token dovrebbero scadere con una frequenza relativamente alta rispetto ai nomi utente e alle password. Dal modo in cui è formulata la tua domanda, sembra che tu stia considerando username e password in ogni richiesta poiché il "livello più alto" di token sta scadendo rapidamente, ma in realtà è il contrario: senza alcun token in mezzo, username e password diventa il token e scade solo se modificato. Ciò rende l'applicazione un po 'più vulnerabile agli attacchi di riproduzione e rende l'inconveniente molto più disagevole per l'utente se si implementano i controlli per rilevare comportamenti malevoli: con un token, è possibile espirare immediatamente il token ma un utente reale può fornire nome utente e password per prendine una nuova mentre un attaccante che ha ottenuto solo il token è bloccato. Un utente che immette le proprie credenziali di tanto in tanto è piuttosto secondario, ma forzare le reimpostazioni casuali delle password è significativamente più oneroso e si appoggia molto su una funzione di reimpostazione sicura della password.

Infine, il nome utente e la password saranno trasmessi molto più frequentemente. Idealmente la connessione sicura è perfetta e non è un problema, ma in pratica ci sono alcune vulnerabilità che sono più probabili essere sfruttabili. Ad esempio, la vulnerabilità CRIME ha sfruttato la dimensione dei messaggi inviati a perdita di informazioni ma ha richiesto un valore costante su più messaggi. Probabilmente l'esatta vulnerabilità è patchata, ma potrebbero esistere simili in futuro e se le tue richieste sono un po 'carenti, avere sempre il nome utente e la password in esse consente a un attacco di mettere insieme le informazioni per un lungo periodo, rispetto a un token che è meno impattante a perdere e limita il tempo che un utente malintenzionato deve procurarselo.

Tutto ciò potrebbe non comportare un compromesso di sicurezza di grandi dimensioni , ma non rischierei di farlo.

    
risposta data 27.04.2018 - 20:37
fonte
0

Firtsly, se un nome utente e una password vengono inviati in ogni richiesta, potrebbero essere esposti in ogni richiesta, ma se hai un canale sicuro (HTTPS), puoi attenuarlo, ma potresti aprire la possibilità a un dizionario attacco o attacco di forza bruta per avere successo, perché un utente malintenzionato potrebbe avere molte pagine della tua applicazione web per testare una combinazione valida di nome utente e password, è possibile limitare il numero di tentativi di accesso su richiesta, ma un utente malintenzionato potrebbe modificare la richiesta quando / lei è stata bloccata. Ora, si dovrebbe considerare che un'applicazione deve avere un equilibrio tra prestazioni e sicurezza, se l'applicazione richiede un nome utente e una password ogni richiesta, quindi le sue prestazioni sono influenzate e gli utenti potrebbero decidere di non utilizzare più l'applicazione per tale motivo. A mio parere, è meglio avere una sessione di gestione di più richieste di autenticazione.

Spero che questa informazione ti aiuti.

    
risposta data 27.04.2018 - 19:23
fonte

Leggi altre domande sui tag