6

Sto lavorando per migliorare la sicurezza del sito Web della mia azienda e ho voluto creare un token per impedire tentativi di contraffazione che potrebbero essere facilmente mantenuti questo è ciò che mi è venuto in mente.Creazione di un AntiForgeryToken tramite Iniezione delle dipendenze

public class AntiForgeryToken 
{ 
    private readonly string _referenceToken; 

    public AntiForgeryToken() 
    { 
     _referenceToken = Guid.NewGuid().ToString(); 
    } 
    public string ReferenceToken 
    { 
     get { return _referenceToken; } 
    } 
} 

Nella mia classe di base per il mio MasterPage ho un HiddenField avvolto con proprietà denominata: ReferenceToken

protected virtual void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
     InjectToken(); 
    } 

    ValidateToken(); 
} 

private void InjectToken() 
{ 
    var token = ObjectFactory.GetInstance<AntiForgeryToken>(); 
    ReferenceToken = token.ReferenceToken; 
} 

private void ValidateToken() 
{ 
    var token = ObjectFactory.GetInstance<AntiForgeryToken>(); 
    if (ReferenceToken.Equals(token.ReferenceToken, SC.InvariantCultureIgnoreCase)) 
      return; 
    ...do stuff for failed token 
} 

devo StructureMap gestire la memorizzazione del token all'interno della sessione in modo che sia persistito per ogni sessione utente, sarebbero tutti di questo è una valida implementazione di uno schema AntiForgery?

Edit: Sembra che ci sia una certa confusione sulla mia domanda, sì ho capito ASP.NET MVC è dotato di un sistema di AntiForgeryToken, questa domanda è esplicitamente di come ricreare questo per WebForms per impedire l'utilizzo di un attacco CSRF (Cross Site Request Forgery). Capisco questo in nessun modo rimuove la necessità di una corretta autorizzazione dei diritti degli utenti.

Stavo per aprire il link che @Neal e @solairaja hanno pubblicato: Prevent Cross-Site Request Forgery (CSRF) using ASP.NET MVC’s AntiForgeryToken() helper. Questo articolo spiega di più su cosa sia l'attacco CSRF e su come MVC lo arresta, tuttavia la loro soluzione non è applicabile alle webform, motivo per cui ho implementato la mia.

Dopo aver visto la risposta di @Neal penso che molto probabilmente sarà la risposta accettata dal momento che non mi ero reso conto che avrei potuto ottenere il vero codice sorgente dallo strumento MVC che molto probabilmente sostituirà la creazione guid. Ma lascerò aperta la domanda nel caso in cui qualcun altro abbia qualche informazione preziosa da aggiungere.

+0

che volevo usare i token MVC in una pagina WebForms - cioè post dal Web Form a MVC e ancora convalidare. Vedere questa risposta: http://stackoverflow.com/questions/1347728/using-an-mvc-htmlhelper-from-a-webform/2553583#2553583 – Keith

risposta

4

Chris,

vostro approccio più o meno imita l'approccio anti-contraffazione in MVC, a meno che usino un base64 array di byte codificato generato da RNGCryptoServiceProvider e memorizzare il token sia nella pagina (campo di modulo nascosto) e in un cookie. Raccomanderei di spostare più della logica nell'implementazione del token (ad esempio incapsulare la maggior parte della logica di convalida all'interno del token).

Il codice per l'implementazione MVC è liberamente accessibile a http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectName=aspnet#391757 se possibile, è consigliabile rivederlo così come http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/ per analisi + idee.

+0

Non sapevo che avrei potuto ottenere la fonte per quello! E sì, ho un incapsulamento molto migliore dell'iniezione/convalida del token che ho appena rimosso tutto per brevità, specialmente quando non offre nulla alla mia domanda reale. Aggiungerò anche la porzione di cookie per seguirne l'implementazione. –

+1

L'implementazione corrente è essenziale per due scopi il cookie di sessione come segnaposto per il cookie anti-contraffazione, quindi non del tutto necessario (ma riduce il carico della sessione). – Neal

-1

Prima regola di sicurezza: Non cercare di ruotare la propria sicurezza

quanto ho capito descrizione, che non sarebbe un sistema di anti-contraffazione valido. Tutto ciò che un utente malintenzionato dovrebbe eludere sarebbe utilizzare la funzione Visualizza sorgente del proprio browser per trovare il token. Poi lui o lei potrebbe postare qualsiasi cosa a loro piacimento purché ricordino di pubblicare quel token, e il tuo codice non conoscerebbe la differenza.

Mi scuso se ho completamente frainteso la tua descrizione ...

+0

Sono sicuro che questo è esattamente il modo in cui il token Microsoft AntiForgery è scritto per MVC che utilizza il campo nascosto nella pagina. Se stavo usando MVC userei la loro funzionalità a prescindere ma non è incluso nei moduli web. –

+0

Ho intenzione di andare con un DV su questo poiché non hai aggiunto alcuna informazione o fornire una soluzione che esiste già per eseguire il backup della prima regola. –

0

In primo luogo, suppongo dovrei chiedere ... cosa realmente intende per "AntiForgery"? Cosa ti preoccupa di essere falsificato? Il resto di ciò che segue è solo alcune informazioni generali che vengono in mente ...

Una cosa che cambierei è non usare Guid.NewGuid. C'è un dibattito sul fatto che sia casuale o meno e quindi non adatto a scopi di sicurezza. Detto questo, penso che sarebbe un attacco molto difficile da realizzare.

Vedere RNGCryptoServiceProvider per il metodo GetBytes per qualcosa che dovrebbe essere migliore per generare un token casuale. Oltre a una migliore casualità, un altro vantaggio è che puoi renderlo qualsiasi dimensione desideri.

Stai facendo questo su ssl però? Prima di tutto, ssl è la linea di difesa numero uno per l'uomo negli attacchi centrali. Potrebbe non essere abbastanza sicuro (e altri possono discuterne) per ogni necessità, ma se sei preoccupato per queste cose, è il punto di partenza se non altro. Altrimenti, come ti assicuri che stai ricevendo una risposta dalla macchina giusta e non da un man-in-the-middle che sta rispondendo per primo?Senza SSL o un equivalente, il tuo token è facilmente rubabile come qualsiasi altra cosa tu faccia.

Un'altra cosa da considerare è che i tuoi token sono validi solo per un viaggio e ne generi uno nuovo al cliente nel prossimo viaggio. Cercare di riutilizzarlo fallisce.

Vorrei non provare a sostituire SSL con qualcos'altro del tuo stesso espediente se questo è quello che stai pensando. Se sei preoccupato per la riproduzione, una volta la generazione di token è un modo per fermarlo. Se sei preoccupato per un utente che invia due volte gli stessi dati del modulo, questa è una cosa da fare. Vorrei anche prendere in considerazione la progettazione generale dell'applicazione se ne sei preoccupato. Molti replay e scenari simili possono essere sconfitti dal sound design della tua logica di business, come non fidarsi del client per inviarti informazioni sensibili come il prezzo di un articolo in un carrello della spesa.

Controllare inoltre le varie indicazioni di microsoft su ASP.NET e la sicurezza IIS (ad es. Google ASP.NET o sito di sicurezza IIS: microsoft.com) come punto di partenza. Molte persone intelligenti hanno già risolto molti problemi per noi.

+0

Sì, questo token si sovrapporrà a SSL per impedire ulteriormente attacchi replay/man in the middle. Non pensavo che il token monouso avrebbe offerto molta più robustezza sia in termini di sicurezza reale, sia semplicemente impedendo agli idioti di fare clic su materiale prima dell'ultimo postback fino a quando non l'avessi presentato. –

+0

L'unica cosa che ho iniziato a pensare con i token monouso è quello che sarebbe un modo efficace per tenere traccia di token validi dal momento che un utente potrebbe avere più finestre aperte, per mantenere un elenco di tutti i token nella sessione e poi alla scadenza per scadere il token rimuovendolo dall'elenco in modo che eventuali tentativi successivi di inviare lo stesso modulo fallirebbero fino a quando la pagina non ha completato il round trip e ha un nuovo token memorizzato nel viewstate? –

0

sarebbe tutto questo essere un implementazione valida di un schema AntiForgery?

Per quanto posso dire, sembra che si stia inserendo un GUID in una pagina e quindi si cerchi lo stesso GUID quando la pagina ritorna.

Non so quali siano le vostre esigenze, quindi non posso dire se lo schema è veramente "valido". Tuttavia, posso evidenziare alcune cose:

  1. Se il GUID vive solo sulla pagina, cosa impedirebbe a un utente di leggere la pagina su una macchina e inviare il modulo da un'altra? Sarebbe bene associarlo con un cookie o una sessione (che utilizza anche un cookie), se non lo si è già.
  2. Se il GUID è scritto nella pagina come campo statico nascosto <input>, il modulo potrebbe essere letto e inviato dai bot. È possibile aggirare questo richiedendo script nella pagina per elaborare il token, prima di inviarlo.
  3. Si sta utilizzando ViewState? In tal caso, potresti prendere in considerazione l'impostazione di ViewStateUserKey per un valore ripetibile che è univoco per client; svolge una funzione simile a ciò che hai descritto qui.
+0

"Ho handle StructureMap che memorizza il token all'interno della Session in modo che sia persistente per sessione utente" –

0

Come ha detto NICK, anche per me il codice che hai fornito, sembra che tu stia inserendo un GUID su una pagina e poi cerchi lo stesso GUID quando la pagina ritorna. È una buona idea anche quando si usa una mappa della struttura che memorizza nella sessione.

Ma ci sono alcuni metodi incorporati disponibili per questi concetti AntiForgery.

rimanda ai link qui sotto prima e capire

http://blog.maartenballiauw.be/post/2008/09/01/ASPNET-MVC-preview-5s-AntiForgeryToken-helper-method-and-attribute.aspx

Ora,

Controllare sul link qui sotto per i dettagli descrizioni e la metodologia di approccio.

http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper_methods.aspx

http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-%20aspnet-mvcs-antiforgerytoken-helper/

Grazie !!

-1

Invece di utilizzare token anti contraffazione come quello, convaliderei che l'utente autenticato abbia effettivamente i diritti necessari per apportare le modifiche richieste.

E.g. è la pagina web "crea pagina utente", vorrei verificare che l'utente autenticato abbia l'autorizzazione per creare nuovi utenti. La pagina è una "pagina utente X di modifica", vorrei verificare che l'utente autenticato abbia l'autorizzazione a modificare l'utente X. Forse perché lui stesso è l'utente X o un utente amministrativo.

Detto questo, l'utilizzo di GUID non è molto sicuro. I Guids sono generati sulla base di un algoritmo scritto per unicità, non casualità. AFAIK ci sono tre algoritmi validi, basati sul nome, basati sul tempo e casuali. Se l'algoritmo Guid utilizzato dal sistema (che potrebbe essere modificato da una futura versione di .NET) è basato sul tempo, quindi indovinare Guids validi non è molto difficile.

+0

DV poiché la mia domanda non riguarda l'autorizzazione/accesso utente –

+0

Pete, per favore vai a leggere http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet -mvcs-antiforgerytoken-helper/per capire il perché/come dei token anti-contraffazione. Un CSRF invierà il cookie di sessione degli utenti e quindi apparirà come un utente autenticato a condizione che l'attacco avvenga nell'ambito di una sessione attiva. I token anti-contraffazione sono progettati come token monouso e quindi la finestra degli exploit viene significativamente ridotta. – Neal

+0

@Neal: grazie per il collegamento, non era a conoscenza di quella particolare vulnerabilità. – Pete

0

Questo mi sembra come se stesse generando un canarino ad ogni richiesta. Ora cosa succede se un utente apre più schede? :)

Il problema con il tuo approccio (e l'implementazione ASP.NET MVC) si basa sugli sviluppatori per implementarlo. La sicurezza come questa dovrebbe essere opt-out, non opt-in. Quando ho scritto un AntiCSRF module ho finito per utilizzare invece il ciclo di vita della pagina ASP.NET, il che significa che non sono state apportate modifiche al codice sottostante, a meno che uno sviluppatore non volesse optare per una pagina dai controlli CSRF. Noterai che utilizza un singolo token che dura per tutta la vita della sessione del browser dell'utente - non c'è bisogno di cambiare il token con ogni richiesta.

Ora ho scritto il modulo principalmente come un modo per illustrare alcuni concetti per il mio indietro proveniente libro (inserto pubblicità qui ghigno), si potrebbe naturalmente utilizzare il ViewStateUserKey, ma ancora una volta questo è opt-in, invece di opt -su.

+0

Penso che tu abbia perso anche dove ho detto che i token sarebbero stati archiviati in sessione da StructureMap. E il codice postato qui è per brevità, come ho spiegato credo a @Neal, ho molto meglio l'incapsulamento dell'iniezione/convalida che in realtà non viene implementato per pagina (quindi è conforme a DRY), è solo irrilevante per il mio domanda. –

+0

Il mio punto era che ti stai ancora affidando agli sviluppatori che ereditano dalla tua classe di base. Se ti colleghi all'evento page_prerender tramite un modulo HTTP, non devi preoccuparti degli sviluppatori che ereditano dalla classe giusta. Non importa dove memorizzi il token su cui controlli (anche se StructureMap funziona in una web farm facilmente?) – blowdart

+0

Ho dato un'occhiata al tuo modulo sembra davvero buono, devo aver cercato con le parole chiave sbagliate su google che non ho potuto trovare questo prima! –

2

ASP.NET Web Form impedisce gli attacchi CSRF fuori dalla casella per impostazione predefinita se si utilizza Visualizza stato. A meno che non si sia disabilitato lo stato di visualizzazione nella propria applicazione, si sta aggiungendo il codice per risolvere un problema che non si ha.

stato di visualizzazione impedisce CSRF Attacchi
.Net CSRF Guard - OWASP