Qui sembrano esserci due elementi trainanti. Cosa vuoi dire all'utente finale e cosa non vuoi dire all'attaccante. La parte più dannosa delle informazioni che potresti rivelare potrebbe essere qualsiasi informazione di temporizzazione relativa all'output dell'errore.
Inoltre, in alcuni attacchi CSRF gli errori possono essere visibili, mentre in altri attacchi gli errori possono essere soppressi o nascosti. Ciò mi farebbe desiderare intraprendere queste azioni in un sito ad alta sicurezza:
-
Termina la sessione e qualsiasi sessione "upstream" che potrebbe essere correlata a OpenID o federazione.
-
Se l'utente ha effettuato l'accesso utilizzando più schede, reindirizza a una pagina che li informa:
- Questo potrebbe essere il risultato di una seconda sessione / scheda di navigazione aperta.
- Informa l'utente o impedisci che ciò accada di nuovo, chiudi tutti i browser e naviga solo un sito alla volta (o utilizza un browser che supporti questa sicurezza in modo nativo)
- Che cosa è successo (i cattivi hanno provato a fare xxxx a yyy) (Attenzione a non riecheggiare i dati dall'attaccante altrimenti questo ti apre fino a XSS)
All'inizio mi è piaciuta la proposta per passare a una schermata di "modifica" che consente a un utente di verificare le modifiche che si stanno tentando. Poi ho pensato alla possibilità del click-jacking e di come questo possa eliminare qualsiasi beneficio. Inoltre, non voglio attivare una "funzione" non supportata del mio sito in cui gli utenti esterni possono pre-compilare un modulo per conto di qualcuno. Offrirò un endpoint dedicato per questo scopo, se lo desideri.
Altre azioni che mi piacciono finora quando gestisco un errore includono:
-
Connessioni di Throttle (Thread.Sleep) che incontrano una delle seguenti tendenze
- Errori per origine indirizzo IP (Attenzione se la fonte è un utente NAT con migliaia di macchine dietro di esso)
- Errori di Referrer (Attento a prevenire un DOS di sistema)
- Pagina di destinazione (Controller / Vista) (sì anche questo può essere DOS)
- Utente connesso (o utente anonimo)
Se noti che una combinazione di questi fattori sta causando molti dei tuoi avvisi CSRF, puoi rallentare e limitare o negare le connessioni finché le condizioni non migliorano. Una metrica potrebbe essere errori / tempo.
Sebbene la maggior parte delle implementazioni consenta un seed, ASP.NET MVC, in particolare, semplifica l'implementazione di un seed costante (compilato) in tutto il sito. Questo constant
può incoraggiare gli attaccanti a cercare di indovinare qual è il tuo seme. Per evitare ciò, sto incollando in qualche codice ASP.NET MVC che risolve alcuni problemi
- Abilita un seed dinamico
- Un luogo centralizzato per avviare la registrazione e il monitoraggio delle eccezioni da tutti i controller.
- Prevenzione della divulgazione di Oracle crittografica dormendo un intervallo di tempo fisso prima che venga generato un errore e inviato al client. Questo è naturalmente ispirato alla mitigazione ASP.NET di Scott Gu , con la caratteristica aggiuntiva di dormire per un periodo di tempo fisso rispetto a un periodo di tempo casuale.
Per iniziare, guarda in questo blog per l'implementazione di base . Quindi modifica il metodo OnAuthorization
come questo
protected override void OnAuthorization(AuthorizationContext filterContext)
{
TimeSpan maxSleepDuration = new TimeSpan(0, 0, 0, 0, 700); //Errors will always take 700ms
DateTime timeStart = DateTime.UtcNow;
base.OnAuthorization(filterContext);
string httpMethodOverride = filterContext.HttpContext.Request.GetHttpMethodOverride();
if (this._verbs.Verbs.Contains(httpMethodOverride, StringComparer.OrdinalIgnoreCase))
{
try
{
this._validator.OnAuthorization(filterContext);
}
catch (HttpAntiForgeryException e)
{
//todo: Custom actions here? Track the IP? Referrer? Do special actions based on IP?
TimeSpan timespent = DateTime.UtcNow - timeStart;
int sleepDuration = maxSleepDuration.Milliseconds - timespent.Milliseconds;
if (sleepDuration > 0 && sleepDuration != System.Threading.Timeout.Infinite)
System.Threading.Thread.Sleep(sleepDuration);
//todo: Error here, or redirect back to validation screen
throw e;
}
}
}
Infine, potresti voler verificare MachineKey non è impostato per il caricamento automatico e garantisce la rotazione di questo tasto nella pianificazione ITOps.