Questo flusso di autenticazione senza password è sicuro?

5

Vorrei implementare un flusso di autenticazione senza password per la mia app per dispositivi mobili che richiede solo un utente che fa clic su un link nella sua e-mail per accedere. Simile a come Slack gestisce auth. Utilizzerò node e jwt per questa implementazione.

Penso di aver trovato un design sicuro, ma sono sicuro che mi manchi qualcosa. Mi piacerebbe qualche critica da parte della community.

Eccoci:

  • L'utente apre l'app per dispositivi mobili.
  • Controlliamo se l'utente ha un token nella sua memoria locale.
  • Se lo fanno, aggiungiamo quel token alle intestazioni e inviamo alla pagina iniziale dell'app.
  • Altrimenti, chiediamo loro di inserire la loro email per iniziare
  • Quando fanno clic su "Invia", POST quello email address all'endpoint requestMagicLink sul nostro server.
  • Il server controlla il database per un utente con quel email address
  • Se troviamo un utente con quella email, prendiamo il id da quell'utente
  • Se l'utente non esiste, creiamo un nuovo utente e otteniamo quel id
  • Usiamo JWT per generare un token con id e il nostro secret che scade dopo 1 hour
  • Inviamo quel token all'utente tramite un link in un'email.
  • Dopo essere stato cliccato, quel link invia una richiesta GET al nostro server al magicLogin endpoint con token in una query param
  • Verifichiamo che il token sia corretto utilizzando JWT e il nostro secret .
  • Se fallisce la verifica, reindirizziamo l'utente alla schermata in cui li chiediamo con la sua e-mail per iniziare.
  • Se ha successo, generiamo un nuovo token JWT usando il loro id e il nostro secret quel doesn't have an expiration , quindi lo restituiamo all'utente nei parametri di un URL che li reindirizza a una pagina di successo in la nostra app.
  • L'app prende il token dal param e lo memorizza nella memoria locale finché l'utente sceglie di disconnettersi e l'utente viene reindirizzato alla home page.
  • Le richieste per l'API ora contengono il token nelle intestazioni e l'utente è a posto.

EDIT (aggiungendo ulteriori pensieri): Qualcosa che sto considerando per renderlo più sicuro: cosa succede se dividiamo il token in 2 parti e inviamo metà al dispositivo mobile e l'altra metà all'email. In questo modo, solo l'utente con accesso a tale email E l'accesso a quel dispositivo specifico sarà in grado di autenticarsi.

    
posta klinore 17.11.2018 - 19:03
fonte

3 risposte

3

Il concetto principale del flusso (collegamenti magici) è una delle alternative più conosciute e prive di password per l'autenticazione. Il consenso generale sembra essere che la sicurezza di tali schemi (come è stato notato nei commenti) non è peggiore di quella di un sistema che consente meccanismi di reset della posta elettronica "dimenticati". Questo ha senso considerando che il punto di errore è ora nella parte e-mail.

I server di posta elettronica non sono generalmente crittografati e la posta può finire archiviata in posizioni non sicure come il client di posta dell'utente. Inoltre, non avrai alcun controllo sulla sicurezza con cui l'utente imposta il proprio account di posta elettronica. Potrebbe anche essere utile (dato che è spesso paragonato ad esso) per ricordare quanto difficile è per implementare una reimpostazione della password in modo sicuro. Alla fine, se questo dovrebbe preoccupare o meno, dipende in realtà dal modello della tua minaccia e dal valore dei dati della tua app.

Le fonti che posso trovare che supportano i link magici e altri schemi senza password sono per lo più da venditori che hanno interesse a spingere le proprie implementazioni di questo sistema (ad esempio Auth0 , okta ) e ci sono alcuni grandi nomi che lo supportano già come amazon-cognito. Puoi anche dare un'occhiata a domande simili da questo gruppo:

Autenticazione senza password nelle app Web - Quanto è sicuro?

login senza password tramite e-mail - considerazioni di sicurezza

Per quanto riguarda la tua implementazione personalizzata, ci sono diverse preoccupazioni da ricordare:

  • Non creare utenti ogni volta che non ci sono indirizzi email esistenti. Gli endpoint e i moduli web sono regolarmente spamizzati e troverai il tuo DB pieno di junk.
  • Potrebbe non esserci la necessità di inviare un token nell'e-mail e invece di inviare direttamente un link. Assicurati che l'URL del link sia generato casualmente e che la scadenza sia impostata per disabilitare l'uso.
  • Come accennato in precedenza, le e-mail possono essere facilmente compromesse, quindi è necessario impostare una scadenza più breve per mitigare. Nella maggior parte dei casi, i tuoi utenti accederanno direttamente alla loro email dopo comunque, quindi lo terrei nell'intervallo di 5-10 minuti.
  • Dopo l'accesso, il JWT dovrebbe anche avere una scadenza anche se è lunga. Non vuoi veramente che i token siano validi indefinitamente.

Ad essere onesti non ti consiglierei di configurarlo tu stesso se puoi evitarlo; Prova a trovare le librerie che supportano già questa funzionalità.

    
risposta data 21.11.2018 - 06:20
fonte
2

Quindi quello che stai cercando di fare è implementare un nuovo "protocollo di sicurezza". Ho una brutta sensazione al riguardo perché penso che questo abbia bisogno di più ricerca e controllo qualità rispetto a una domanda su stackexchange. Nuovi protocolli (Auth2) o algoritmi (AES) richiedono molto tempo e sforzi nella ricerca prima che siano generalmente considerati "approvati" o "sicuri".

In generale, ritengo che la posta non sia il modo migliore per condividere i token di accesso. Si dice, si crea un token con un segreto, si invia un collegamento con questo token come parametro di query a un indirizzo e-mail e quando l'utente fa clic su questo link, viene considerato come autenticato. Manderesti anche una password in chiaro a un utente e poi inserirai questa password tramite parametro di query sul filo? Spero che tu non lo farai perché è una pratica veramente pessima, ma se ti capisco di correggere, vuoi fare esattamente questo: invia il "ticket" che fornisce all'utente l'accesso alla tua app in chiaro via mail. Anche se è criptato, non è una buona pratica.

Inoltre, non devi "creare" automaticamente il nuovo utente se ricevi un POST alla requestMagicLink-endpoit con un indirizzo di posta sconosciuto: questo dà a un utente malintenzionato l'opportunità di inviare spam al tuo db con indirizzi di posta da utenti che non indossano vuoi i loro indirizzi di posta nella tua app; -)

Alcune altre insidie che penso spontaneamente:

  • L'invio di e-mail è sempre complicato: gli hacker possono inviare email false ai tuoi utenti o catturare e leggere messaggi inviati perché le e-mail non sono crittografate
  • Il reindirizzamento è sempre complicato: gli hacker possono compromettere un sistema implementato in modo inadeguato per reindirizzare gli utenti a un sito Web compromesso sotto il loro controllo
  • Mantieni il ciclo di vita il più breve possibile - se l'utente non ha fatto clic sul link nella posta dopo 10 minuti, rifiutalo
  • Non inviare mai dati privati tramite parametri di query, né nelle richieste GET né in tutti gli altri metodi
  • Possibilità di attacchi di replay quando un token può essere utilizzato più volte

Ti consiglierei di utilizzare protocolli e metodi di best practice per l'autenticazione che vengono utilizzati e verificati per anni invece di scrivere il tuo meccanismo solo per impedire all'utente di inserire una password. Altrimenti, se vuoi davvero andare in questo modo, dovresti collaborare con i professionisti e spendere un sacco di tempo e sforzi per garantire la sicurezza del tuo meccanismo.

    
risposta data 20.11.2018 - 14:51
fonte
1

Non inserire token / segreti di accesso nella memoria locale

Inserendo il token di accesso nell'archivio locale, sarà accessibile tramite JavaScript. Ciò significa che il token può essere rubato con XSS ( Script cross-site ). Inoltre, l'autenticazione funzionerà solo se JavaScript è abilitato.

Un'estensione del browser dannoso potrebbe estrarre il token di accesso e inviarlo a un utente malintenzionato. Questo è particolarmente importante se, come dici tu, il token di accesso non scade.

Per prevenire il rischio di XSS, è meglio usare i cookie per tali token con il flag HttpOnly impostato. (Dovrai anche utilizzare il flag Secure e forzare HTTPS per tutte le connessioni)

NOTA: quando si utilizzano i cookie anziché la memoria locale, è necessario considerare e proteggiti dagli attacchi CSRF ( Richiesta di cross-site ).

Risorse utili:

risposta data 25.11.2018 - 18:41
fonte

Leggi altre domande sui tag