2013-03-15 11 views
5

I campi MongoDB _id sono sufficientemente casuali/non selezionabili da agire come dati segreti?Utilizzo di _id come MongoDB come "dati segreti" (ad esempio, token OAuth)

Ad esempio: se sto creando un OAuth lato server, potrei utilizzare _id come token OAuth per l'utente? Voglio farlo a causa della facilità di indicabilità & che fornisce al database (ad esempio "tokens._id" => oauth_token).

Ispezionando la struttura degli oggetti _id di MongoDB, sembrano essere decentemente casuali, ma ho qualche preoccupazione persistente riguardo a una entità bruta che indovina la forza bruta.

risposta

11

In breve, no. Mongo ObjectIds sono facili da indovinare. In particolare, in caso di carico elevato, si tratta spesso di numeri consecutivi, poiché timestamp, id macchina e processo non cambiano. Se si guarda alla the structure of Objectid, sono composti da

a 4-byte timestamp, 
a 3-byte machine identifier, 
a 2-byte process id, and 
a 3-byte counter, starting with a random value. 

Di conseguenza, essi hanno ben poco casualità. Spesso vedo ID consecutivi nel database, ad esempio se un'azione del controller scrive un oggetto dominio e una voce del registro in rapida successione.

Se il timestamp può essere indovinato e l'id della macchina è determinabile (che è a meno che non si disponga di un cluster enorme), rimangono solo cinque byte. Osservando un numero di ID generati, posso probabilmente ridurlo a 50 processi così l'entropia effettiva è da qualche parte nell'intervallo di 28 bit. Questo è ancora difficile da indovinare, ma è troppo rischioso per un token di accesso.

Utilizzare invece un generatore di numeri pseudo casuali crittograficamente avanzato e creare un token da esso. Ad esempio, in .NET, lo RNGCryptoServiceProvider consente di creare dati casuali di lunghezza arbitraria.

Come sidenote, suggerisco di avere un involucro crittografico ulteriore intorno ai vostri OAuthTokens, per due motivi:

a) Si vuole essere in grado di determinare i token non validi in fretta. Una shell crittografica valida potrebbe ancora includere un token non valido (una concessione revocata o scaduta), ma non è necessario colpire il database con attacchi di forza bruta ogni volta. Inoltre, il client

b) I client possono richiedere più volte token. Sebbene non sia un requisito, quasi tutti i sistemi che conosco restituiscono sempre diversi token (indipendentemente dal fatto che siano auto-validanti o meno). Di solito, è perché il token stesso ha un periodo di validità limitato. Questo non è lo stesso periodo di validità della concessione OAuth.

Nel database, ciò che si desidera archiviare è la concessione, ovvero l'autorizzazione concessa da alcuni utenti a un determinato cliente. Se questa sovvenzione viene rimossa, tutti i token diventano non validi. L'inserimento di un nuovo token ogni volta è molto difficile perché l'utente dovrebbe eliminarli tutti per rimuovere la concessione dell'applicazione.

+1

Buona risposta, grazie. Ho creato un cripto wrapper per generare ora token di accesso, e in realtà significa che ho 1 hit di database in meno per query, che è bello;) –

0

La valutazione è possibile anche se estremamente difficile. In realtà potresti avere una migliore possibilità di indovinare la maggior parte degli altri token OAuth.

Un esempio di come può diventare molto difficile è che contiene il PID. Se stai usando un linguaggio come PHP o qualcosa del genere, il PID cambia in ogni processo PHP generato, il che significa che ogni _id potrebbe avere il proprio PID in movimento ed essere completamente e completamente casuale, ovviamente dipende dalla modalità in cui esegui PHP; se in modalità fcgi, il PID potrebbe essere costante.

L'id di mahcine è anche un altro. La maggior parte dei siti web dispone di cluster automatici di server per il loro database, quindi anche con carichi pesanti ecc. L'unica variabile reale prevedibile è il timestamp in molti casi e anche allora, dato che è a un millisecondo, non è ancora facile indovinare ; è necessario sapere esattamente quanto traffico il sito ha dovuto costruire un algoritmo per calcolare il tempo in modo ragionevole. Ovviamente l'unico modo per guarnire le informazioni in primo luogo è quello di ottenere i suoi _id's, catturare 22.

Tuttavia, ciò considerato, l'unico modo in cui posso pensare a forzare il bruto a _id è di ottenere sufficiente potenza di calcolo per iterare tutti i ObjectId che potrebbero mai esistere (potrebbe essere trilioni/infinito qui considerando la casualità delle variabili di un ObjectId) e quindi eseguire il ping di ogni ID app (dovresti richiedere un token OAuth e un ID app in ogni momento) database che fornisce ancora un altro livello di mistero qui.

Quindi, a mio parere, sì, qualcuno potrebbe avere una forza bruta, ma ci vorrebbe un sacco di potenza di calcolo e forse anche un paio di anni per rompere qualcosa che non vale davvero la pena.

Problemi correlati