L’attuazione di sicuro, l’unico “single-use” attivazione Url ASP.NET (C#)

Ho un scenario inwhich gli utenti di un sito che sto costruendo la possibilità di inserire alcune informazioni di base in una webform senza dover effettuare l’accesso. Il sito è sviluppato con ASP.NET/C# e utilizza MSSQL 2005 per i suoi dati relazionali.

Utenti verrà inviata una e-mail dal sito, fornendo loro un unico link per inserire le informazioni specifiche che sono necessarie. L’e-mail sarà molto simile allo stile di posta elettronica che siamo tutti al momento della registrazione per siti come forum, contenente un generati in modo casuale, URL unico parametro in particolare appartenenti a un unico scopo (come ad esempio la verifica di un indirizzo email di un forum).

Le mie domande sono per quanto riguarda l’implementazione sicura di questo problema. Stavo pensando di utilizzare un GUID come identificatore univoco, ma sono sicuro delle sue implicazioni nel mondo della sicurezza.

  1. È un GUID sufficientemente lungo tale che i valori non possono essere facilmente indovinato (o forzati nel tempo)?
  2. È .NET GUID un’implementazione sufficientemente casuale, nel senso che c’è un’uguale probabilità di generazione di tutti i possibili valori del tasto “spazio”?
  3. Se si utilizza un GUID è un approccio accettabile, qualora il sito quindi reindirizzare le informazioni attraverso la riscrittura dell’URL o associando le informazioni in un datatable con il GUID come riferimento?
  4. Si utilizza un URL rewriting nascondere la vera origine dei dati?
  5. Devo considerare l’utilizzo di TSQL SELEZIONA NEWID() come generatore di GUID oltre il .NET attuazione?
  6. Ho completamente sbagliato il mio approccio a questo problema??

Molte grazie,

Carl

InformationsquelleAutor Tyst | 2009-06-02

 

6 Replies
  1. 11
    1. Sì, 2128 è abbastanza lungo.
    2. No, GUID implementazioni sono progettati per generare unico Guid piuttosto che quelli casuali. Si dovrebbe utilizzare un crittograficamente sicuro generatore di numeri casuali (ad esempio RNGCryptoServiceProvider) per la generazione di 16 byte casuali e inizializzare un Guid struttura con quella.
    3. Sì, è un approccio accettabile nel complesso. Entrambi funzionano.
    4. Sì, se non si può dare altri indizi
    5. No, goto 2
    6. No, è abbastanza OK. Hai solo bisogno di utilizzare un crittograficamente sicuro generatore di numeri casuali per generare un GUID.
    • Spiacente, ma questo è veramente sbagliato e fuorviante Guid non sono buone per questo tipo di cose, vedi la mia risposta qui sotto.
    • GUID, nel senso di identificatore univoco non è molto adatta (come ho detto nel #2). Ma non c’è nulla per impedire l’uso di loro, come a 128 bit numero.
    • Ma la cosa è che sono non davvero 128 bit di numeri (anche se non a 128 bit per memorizzare loro). Ancora una volta, troppo gran parte di essa è statico, o facili da indovinare. Guid usare in sicurezza gli identificatori. Quello che l’OP ha bisogno è qualcosa di sicuro, e abbastanza a lungo, nel senso di “a 128 bit di casualità”, che Guid non sono, non è nemmeno vicino.
    • La cosa è, non usare Guid.NewGuid() e la funzione NEWID() come ho detto esplicitamente. Si utilizza un CSRNG per generare 16 byte casuali e ottenere un GUID rappresentazione da esso.
    • Ah, vedi CRNG fare non generare un Guid. Un GUID, ha una struttura molto specifica, che non è casuale, solo una piccola parte di esso è.
    • Oh, e mentre stiamo menzione – 16 byte di dati casuali NON tradurre a 16 caratteri – dal momento che ci saranno un sacco di byte che sarebbe rappresentato da caratteri non stampabili, è necessario base64 codifica. In tal modo si otterrà una lunga stringa di output, più simile a 24 caratteri… ma ancora una volta, questo non è di 24 byte vale la pena di casualità, a soli 16 anni.
    • GUID non è 16 caratteri ASCII. E ‘ di 32 cifre esadecimali = 16 byte che si riempie con 16 byte di dati casuali. Non vedo una relazione qui.
    • GUID è non 16 byte di dati casuali, ha una struttura molto specifica, di cui i primi (la maggior parte) byte NON sono casuali. L’elemento casuale è solo negli ultimi byte.
    • Non ho mai detto che si desidera generare un GUID chiamando Guid.NewGuid. Che mi interessa è il formato GUID. Si genera 16 arbitraria di byte con un generatore di numeri casuali e la confezione in un formato GUID. Sì, non può servire come un Identificatore Univoco Globale, ma non importa. GUID formato è solo un comodo formato.

  2. 14
    1. No, Guid non sono completamente casuale, e la maggior parte dei pezzi sono statici o facili da indovinare.
    2. No, non sono casuali, vedere 1. In realtà c’è un piccolo numero di bit che sono effettivamente casuali e non casuali crittograficamente sicuro che.
    3. Non, vedere 1 e 2.
    4. è possibile, ma non necessario… vedere la mia soluzione alla fine.
    5. No, vedi 1 e 2
    6. Sì.

    Ciò che si dovrebbe essere utilizzando invece di un GUID, è un crittograficamente forte generatore di numeri casuali – utilizzare Sistema.Di sicurezza.Crittografia.RNGCryptoServiceProvider, per generare lunga (diciamo, 32 byte) stringa di dati, quindi base64 codifica che.

    Inoltre, supponendo che questo sia un qualche tipo di registrazione con i dati sensibili, vuoi per il limite di tempo di validità del link, diciamo 60 minuti o 24 ore, a seconda del tuo sito.

    Avrete bisogno di mantenere una mappatura di questi valori, per gli utenti specifici. Poi si può automaticamente lui con la forma corretta, come necessario. Non è necessario fare la riscrittura degli url, basta usare quella come identificatore (su questa pagina).

    Naturalmente, non dimenticate l’URL deve essere HTTPS…

    Btw, solo una nota – è buona pratica mettere una qualche forma di testo nella e-mail, spiegando che gli utenti devono fare clic sul link nella e-mail anonime, e di solito il vostro sito inviare, e che non deve mai inserire la propria password dopo aver cliccato blablabla….

    Oh, ah dimenticavo, un altro problema che si dovrebbe prendere in considerazione è quello che succede se l’utente vuole più messaggi di posta elettronica inviati a lui, ad esempio, colpisce registrare più volte. Può fare questo più e più volte, e ottenere molti validi Url? È solo l’ultimo valido? O magari lo stesso valore si risentono più e più volte? Naturalmente, se un utente anonimo può mettere in una richiesta di questa e-mail, il DoS può diventare un problema… per non parlare che se si mette in proprio e-mail, si può mettere in qualsiasi indirizzo casuale, troppo, inondazioni alcuni poveri shmuck posta in arrivo e, eventualmente, causando il vostro server di posta elettronica per ottenere nella lista nera…

    Non una risposta giusta, ma deve essere considerato nel contesto dell’applicazione.

  3. 4

    Potrebbe essere esagerato, ma si potrebbe hash, il loro indirizzo email con SHA1 utilizzando il guid (NewGuid va bene) come hash sale e che nella URL. Poi, quando arriva alla tua pagina, si potrebbe chiedere loro il loro indirizzo email, recuperare il guid e ricalcolare l’hash per la convalida. Anche se a qualcuno dovesse sapere quali indirizzi e-mail di provare, non sarebbero mai in grado di generare un hash collision senza sapere guid salata con (o sarebbe prendere loro un inferno di un tempo :). Naturalmente, è necessario salvare la loro e-mail e l’hash sale guid nel database.

    • Sebbene tecnicamente ha risposto alle mie domande direttamente, mi piace il tuo attuazione idea. Dopo qualche riflessione ho expaneded su di esso alcuni: URL = SHA1(e-mail + randomPass + sale) serverHash = SHA1(e-mail + randomPass) le Colonne della Tabella: serverHash (chiave primaria) sale Il randompass anche essere inviata con url nell’e-mail e utilizzato l’URL originale il calcolo quindi scartato. Credo che in questa realizzazione non sono dati sensibili potrebbero essere memorizzati nel database. Significa che anche se il raw datatable sono stati esposti si poteva generare l’URL di tipo brute-force, l’indirizzo e-mail
    • Felice di aiutare. Una nota sulla tua soluzione, si apre un nuovo caso di utilizzo in quanto non è possibile ricreare l’e-mail. L’utente, quindi, le richieste e-mail, non fa nulla con esso, le richieste di un altro e quindi fa clic sul link nella prima e-mail (come sono sicuro che voi sapete, gli utenti di fare cose del genere 🙂 in questo Modo, si avrà la scadenza di ogni ServerHash mantenendo la data in cui hai inviato l’e-mail nel DB, e dà all’utente un ragionevole lasso di tempo per rispondere.
    • Yup, grazie. Mi rendo conto di questo. Le e-mail e Url generati sono molto specifici e generato per consentire agli utenti, in generale, di salvare se stessi un po ‘ di soldi, così si dovrebbe usare loro, ma io a implementare alcuni trattamenti anche.
    • La maggior parte di salatura suggerimenti che ho letto consigliamo di aggiungere il sale all’inizio in contrapposizione alla fine.
  4. 4

    Mi sento di raccomandare utilizzando un semplice numero casuale, ad esempio byte da RNGCryptoServiceProvider.GetBytes . Guid non sono destinati ad essere del tutto casuale. Hanno risolto i bit, e alcune versioni di utilizzare l’indirizzo MAC. GetBytes dà anche la possibilità di utilizzare più di 128 bit (anche se che dovrebbe essere un sacco).

    Penso che è meglio non mettere i dati dell’utente in un url. Se HTTPS può proteggere in transito, può ancora essere nel browser dell’utente, la storia del genere. È meglio usare il POST e associare il numero casuale con una riga del database.

  5. 1

    Prima, se possibile, si dovrebbe limitare la forza bruta, limitando la velocità effettiva della query (ad es. limitato di tentativi per ogni IP al secondo, e in totale solo cerca di un secondo).

    A seconda del GUID algoritmo di generazione, questo potrebbe non essere una buona idea. Mentre recenti implementazioni dovrebbe essere abbastanza buono “di solito”, non ci può essere un sacco di prevedibilità dei valori. Recenti implementazioni usato nel .NET applicare un hash, altrimenti si hanno chiaramente identificabili campi per l’indirizzo MAC, e ora dall’avvio. Tuttavia, i valori possibili sono limitate, quindi non hanno un vero 128 bit casuali.

    Se la sicurezza è la priorità assoluta, prenderei un crittograficamente forte generatore di numeri casuali, e costruire una stringa di caratteri casuali. Questo rende anche oyu indipendente facili da indovinare algoritmo (come un guid.ToString() è facilmente identificabile in quanto tale), per cui un attacco potrebbe essere scoperto in un prossimo futuro.

    Se questi criteri sono soddisfatti, non vedo alcun problema nell’avere la chiave nella stringa di query.

  6. -1

    creare una tabella nel database con un linkID e un Datesent colonna, sulla generazione del collegamento inviare inserire DateTime.Ora nella tabella e ritorno linkId, impostare il linkID come parametro querystring sul activationLink. Al caricamento della pagina di attivazione recupera il linkId e si usa per evocare una stored procedure che restituisce la data in cui, superato il che corrisponde linkId come parametro, quando si ottiene la data di ritorno si può aggiungere quanto tempo si desidera che il collegamento per rimanere attiva utilizzando il .AddDays()/.AddMonths questo sono metodi di C# per datetime. quindi confrontare la data è tornato con la data di oggi. se ha superato la sua lunghezza di giorni o di mesi dare un messaggio di errore o di altro continuare e visualizzare il contenuto della pagina. Io suggerisco è di mantenere il contenuto della pagina in un pannello e impostare vissible = “false” quindi solo per rendere il pannello visible=”true” se la data è ancora all’interno della gamma.

Lascia un commento