Come posso creare e-mail di accesso sicure? (GET / POST) [duplicato]

3

Vision

Immagino un sistema di accesso / registrazione, in cui l'utente immetta la sua email e riceve un'e-mail con un link per accedere. L'utente fa clic sul link ed è automaticamente connesso (confermando l'indirizzo e-mail nel processo).

Questa sarebbe una forma di autenticazione senza password.

Problema

Il problema che vedo con questo approccio è che un link invierà una richiesta GET - ma questa richiesta GET cambierà lo stato della sessione utente (attivandola).

Le richieste GET dovrebbero (in base allo standard HTTP) non avere mai effetti collaterali. Questo è qualcosa che i browser assumono anche, il che significa che potrebbero prefetch le richieste GET per ottimizzare le prestazioni / l'esperienza utente.

Supponiamo che tu stia utilizzando Gmail nel browser. Potrebbe quindi accadere che il browser precarri il collegamento nell'email?

Sarebbe un enorme problema di sicurezza se fosse sufficiente aprire l'e-mail per accedere al sito.

Cosa ho considerato

Uso di JavaScript nella pagina di destinazione per inviare una richiesta POST

Il mio istinto mi dice che, anche se HTML / CSS / JavaScript da un collegamento può essere precaricato, nessuno di questo codice (specialmente il JavaScript) verrà eseguito prima che il browser apra esplicitamente il link.

Questo dovrebbe significare che se la sessione utente viene in qualche modo attivata usando JavaScript (inviando una richiesta POST al back-end), dovrebbe essere sicuro usare una richiesta GET per arrivare a questa pagina (come link nell'email).

Ho ragione assumendo questo?

È una cattiva pratica farlo in questo modo?

Utilizzo di un modulo HTML nel corpo dell'e-mail

Un'altra opzione sarebbe quella di inserire un modulo nell'e-mail, che consentirebbe una richiesta POST direttamente dall'e-mail.

Sembra, tuttavia, che diversi client di posta elettronica bloccheranno le richieste di invio da e-mail. I client di posta elettronica che consentono l'invio di moduli tendono ad avvisare l'utente che l'email è probabilmente dannosa. Sembra che questa non sia davvero una buona soluzione.

    
posta Tobias Bergkvist 23.11.2018 - 03:09
fonte

1 risposta

5

Quindi, prima di tutto, i link dall'email cambiano lo stato per tutto il tempo . Mentre i GET non idempotenti sono una violazione dello standard de jure, lo standard di fatto è che qualsiasi browser o sistema di posta elettronica che non consente agli utenti di effettuare richieste GET per cose come la verifica della posta elettronica, la reimpostazione della password e vari altri servizi che utilizzare un login senza password basato su e-mail (come Slack) è un browser o client di posta che tutti considereranno rotto. Un altro esempio comune è il collegamento "logout" (che su molti siti è solo un GET per link , senza nemmeno alcuna protezione CSRF); mentre questo è potenzialmente un rischio per la sicurezza, in pratica è estremamente usato e difficile da sfruttare come qualcosa di diverso da uno scherzo.

WITH THAT SAID il modo standard per gestirlo è che il link nell'email contenga un token (strong random unique) che porta l'utente a una pagina di destinazione e la pagina di destinazione dice, in sostanza, "hey, sembri essere [nome utente], fai clic QUI per accedere" insieme a "Non [nome utente]? Clicca invece QUI" link in testo più piccolo sotto. Il link inviato via email scade dopo che si fa clic su un link nella pagina di destinazione, o dopo che è trascorso un certo periodo di tempo (in genere non più di un'ora), a seconda dell'evento che si verifica prima. Il caricamento della pagina di destinazione non fa scadere immediatamente il collegamento, tuttavia, e i "link" nella pagina di destinazione possono tranquillamente essere pulsanti su un modulo HTML quali POST al tuo servizio o trigger JavaScript. I "link" nella pagina di destinazione dovrebbero idealmente avere la protezione CSRF.

Questo ha alcuni vantaggi:

  • Nessun problema se la pagina di destinazione viene visitata "in anticipo".
  • Non c'è modo per un utente malintenzionato di ingannare qualcuno a partecipare per errore.
  • Non sono necessarie richieste GET che cambiano lo stato (sebbene l'evento JS potrebbe semplicemente attivare una navigazione su una pagina "completa questo accesso" imprevedibile, se non ti interessa quella parte della specifica) .
  • Consente all'utente di annullare l'accesso se ha fatto clic sul link per sbaglio o ha più account e ha utilizzato quello errato per errore.

Ha anche alcuni svantaggi:

  • L'utente deve fare clic su un tempo aggiuntivo. Puoi mitigarlo avendo un timeout che registra automaticamente l'utente dopo qualche secondo, se non fa clic su nulla o chiude la pagina.
  • Il token inviato nell'URL può potenzialmente rimanere attivo per un periodo dopo essere stato visitato. Questo è un rischio perché a volte gli URL vengono registrati in luoghi in cui gli utenti non attendibili potrebbero vedere o sono altrimenti esposti. Non penso che ci sia alcuna attenuazione per questo (oltre ad avere una vita molto breve) oltre a rendere il link stesso monouso, che rompe entrambi "GETs dovrebbe essere idempotente" (non in realtà un grosso problema, come spiegato sopra) e "pre-recupero di questo URL non dovrebbe distruggere roba" (vedi sopra).

Per inciso, i servizi di webmail e i sistemi di chat basati sul web e così via riscrivono quasi sempre i collegamenti nei messaggi ricevuti (prova a copiare il link effettivo da un messaggio di Gmail, ad esempio, il testo della barra di stato è una bugia). Quando si fa clic sul collegamento, viene rimbalzato attraverso una pagina di reindirizzamento in un'altra scheda, anziché aprire direttamente la destinazione in quell'altra scheda. Questo impedisce cose come la pagina collegata a usando la proprietà window.opener per confondere con la pagina webmail / chat.

    
risposta data 23.11.2018 - 08:48
fonte

Leggi altre domande sui tag