sha512 come token non necessario per l'accesso

4

Il mio sito ha un sistema di abbonamento alle notizie. Quando un elemento viene aggiornato, una e-mail di notifica viene inviata a tutti coloro che sono abbonati a quell'elemento.

Puoi annullare / iscriverti tramite un modulo sulla pagina di ciascun elemento.

Volevo includere un link di annullamento dell'iscrizione diretto nelle e-mail di notifica. Poi ho pensato che le persone potessero essere disconnesse o visualizzare l'e-mail su una macchina diversa dal loro login (non permettiamo agli utenti di essere simultaneamente loggati su macchine diverse), quindi volevo creare una funzione di annullamento dell'iscrizione con un clic che non richiede l'accesso di qualcuno.

Ovviamente, questo significava un token (si spera) unico.

La mia soluzione di prova è questa:

  1. quando un utente si iscrive a un elemento, un token viene generato tramite sha512 su una stringa concatenata di varie cose (nome utente, datetime, itemid, ecc.)
  2. il link di annullamento dell'iscrizione include l'ID dell'articolo, il tipo di elemento e il token come parametri GET
  3. se e solo se tutte e tre le cose sono abbinate su una riga nel database user_subscriptions , la riga viene rimossa e termina la sottoscrizione

Funziona, e ho il sospetto che sia adeguato per questo compito non sensibile alla sicurezza di iscriversi e annullare l'iscrizione ai post di notizie.

Ciò che mi porta a Security.SE è la domanda più ampia di quanto è sicuro un tale sistema di token per altre azioni?

sha512 produce un hash di 128 caratteri, oltre a dover inchiodare l'ID e il tipo di azione che desideri eseguire ...

    
posta Drew 06.02.2012 - 03:49
fonte

4 risposte

3

Un problema di sicurezza con il tuo approccio è che tutto ciò che stai facendo è potenzialmente ipotizzabile. Di conseguenza, i token potrebbero essere immaginabili.

Una semplice correzione consiste nel generare il token in modo casuale: utilizzare una stringa casuale a 128 bit da una sorgente crittograficamente casuale (ad esempio /dev/urandom o CryptGenRandom ) per formare un token monouso. Archiviare il token nel database insieme alle informazioni sull'azione desiderata e quando si riceve una richiesta, se contiene un token trovato nel database, eseguire l'azione suggerita da tale voce del database ed eliminare il token. Se segui questo approccio, non includere elementi come ID articolo, tipo di elemento, ecc. Nell'URL. Invece, memorizzalo nel database.

In alternativa, potresti includere alcuni segreti non guidabili (ad es. una chiave crittografica a 128 bit) come parte dell'input della funzione di hash. Quando si riceve la richiesta, è necessario ricalcolare la funzione di hash (utilizzando i parametri nella richiesta) e assicurarsi che il token fornito sia corretto. Assicurati che tutti i parametri nell'URL siano inclusi come parte dell'input della funzione hash (altrimenti qualcuno potrebbe cambiare quel parametro senza invalidare il token).

Come osserva @AaronS, se qualcuno inoltra l'email, il destinatario dell'email inoltrata impara il token. Quindi, questo schema non è perfetto. Per alcuni usi (ad es. Annullamento dell'iscrizione), potrebbe essere sufficiente. Per gli altri (ad esempio, la gestione dell'accesso a un conto bancario online), non è una buona scelta.

    
risposta data 06.02.2012 - 08:23
fonte
3

Vuoi un MAC . Ecco di cosa tratta il tuo hash personalizzato: un modo per assicurarti che l'URL su cui l'utente fa clic sia un "vero" URL per quell'utente , ovvero un URL prodotto dal tuo sistema, non qualcosa calcolato da qualcun altro. Questo porta a due soluzioni:

  1. Produce un token casuale per utente e lo memorizza nella tabella utente. Quando si invia una e-mail a un utente, includere l'URL "unsubscribe" che include il token casuale e il nome dell'elemento di destinazione (quello da cui l'utente deve essere annullato). Non preoccuparti di inserire altre informazioni nell'URL, il token casuale è sufficiente. Sul server, si mantiene un indice sulla colonna che contiene i token casuali, in modo da poter facilmente associare i token all'ID utente. Quando il server Web riceve una richiesta per un URL-con-token, annulla l'iscrizione dell'utente.

    Questo funzionerà fintanto che produrrai i token casuali con un PRNG crittograficamente strong (ad esempio /dev/urandom su un sistema Linux) e renderli abbastanza grandi da ridurre il tasso di successo dei "tentativi fortunati" a valori trascurabili. 16 byte dovrebbero essere sufficienti.

  2. Mantieni una chiave segreta lato server. Per calcolare un URL di annullamento dell'iscrizione per un elemento e un utente, includere nell'URL tre elementi: l'elemento di destinazione, l'ID utente e un MAC calcolato rispetto agli altri due valori ( HMAC / SHA-256 andrà bene per quello), usando il tasto server come tasto MAC. Quando il server Web riceve una richiesta di annullamento dell'iscrizione, estrae gli elementi e ricalcola il MAC: se corrisponde a quello nell'URL, quindi procedi alla disiscrizione.

    Rispetto al metodo precedente, questo non richiede alcuna memoria aggiuntiva nel database. D'altra parte, ora hai una chiave da gestire; questo può essere un po 'imbarazzante in alcuni setup, specialmente quando ci sono diversi server frontend.

Ovviamente , l'intero concetto dell'URL di annullamento del one-click presuppone che i contenuti dell'email siano sufficientemente riservati, per quanto riguarda la posta in gioco (poiché la disiscrizione alle notizie è una questione piuttosto banale , email "security" è probabilmente sufficiente).

    
risposta data 09.02.2013 - 16:52
fonte
1

when a user subscribes to an item, a token is generated via sha512 on a concatenated string of various things (username, datetime, itemid, etc.)

Per assicurarti che la crittografia sia solida, utilizza un codice di autenticazione dei messaggi ben accettato come HMAC -SHA per firmare dettagli, preferibilmente a un semplice hash.

Oltre al timestamp di scadenza, puoi anche considerare un numero di sequenza specifico dell'utente che viene aggiornato ogni volta che un utente cambia la password, in modo che una modifica della password invalidi i token emessi in precedenza.

Dovrai assicurarti che i dati firmati non cambino significato. Ad esempio, qualsiasi ID univoco non viene riutilizzato dopo un'eliminazione, pertanto l'elemento a cui fa riferimento un token non cambia. Inoltre, se una risorsa dispone di autorizzazioni modificabili, sarà necessario eseguire l'autorizzazione sia in fase di generazione che di ricezione, in modo che un token emesso per un'azione non autorizzi l'utente a eseguire tale azione dopo una modifica che rimuova le autorizzazioni.

how secure is such a token system for other actions?

Un token con firma HMAC di lunghezza adeguata è generalmente abbastanza stretto. La preoccupazione sarebbe come li distribuisci: chiaramente la posta elettronica non è un canale meravigliosamente sicuro.

    
risposta data 06.02.2012 - 09:04
fonte
0

Le persone possono inoltrare la tua e-mail ai propri amici e quindi l'amico può fare clic sul link. Quindi, soprattutto se non cambi questo hash per ogni email, non è davvero un segreto.

Se hai bisogno di "non ripudio", questa non è una soluzione.

A

    
risposta data 06.02.2012 - 07:07
fonte

Leggi altre domande sui tag