Come dovrebbe rispondere una pagina web a un attacco CSRF?

10

So che usi token per prevenire CSRF, ma come dovrebbe rispondere la pagina ricevente quando viene attaccata? Se fallisce silenziosamente, fingere che la transazione abbia avuto successo? Mostra un messaggio di errore? Registra l'attacco?

Spiega il tuo ragionamento per la tua risposta, poiché mi piacerebbe capire il perché dietro una best practice.

Modifica :

Alcune delle risposte finora sembrano sostenere gli utenti fornendo un messaggio di errore di qualche tipo. Una parte a cui non ho pensato quando ho posto questa domanda è la possibilità di falsi positivi. Forse non sono abbastanza fantasioso, ma sto facendo fatica a creare uno scenario in cui un utente legittimo viene confuso come un attacco CSRF nel corso del normale utilizzo di un sito web. Qualcuno può spiegare come potrebbe accadere? Come verrebbe visualizzato il messaggio di errore CSRF se un CSRF non era effettivamente in corso?

Se un utente può attivare in modo accidentale un messaggio di errore CSRF visibile, immagino di poter vedere il punto, ma se non ci riescono, non sono sicuro del motivo per cui vorresti visualizzarne uno. Presumibilmente l'attaccante saprebbe che stanno attaccando, quindi dare loro un messaggio di errore sembra inutile o dare loro più informazioni di quanto dovrebbero. Se qualcuno potesse chiarire, mi aiuterebbe a capirlo più pienamente.

    
posta VirtuosiMedia 28.10.2011 - 07:48
fonte

3 risposte

5

Nel caso in cui si stia utilizzando una soluzione segreta per token per contrastare gli attacchi CSRF. Ci possono essere molte strategie di risposta nel caso in cui non si ricevesse il token segreto nella richiesta in cui ci si aspettava (non entrerò quando dovresti includere / escludere i token). Devi mantenere un equilibrio tra usabilità e sicurezza

Alcune delle possibili risposte all'utente possono essere

  • Invalida la sessione e porta l'utente alla pagina di scadenza della sessione generica. Questa pagina può essere una pagina comune per il timeout inattivo, l'uso del pulsante Indietro / Aggiorna ecc. Questo dovrebbe essere preso in considerazione per i siti Web come transitorio, gestendo dati molto sensibili ecc.

  • Non invalida la sessione, chiedi all'utente di noleggiare la password

  • Reindirizza l'utente a una pagina di conferma prima di elaborare la richiesta

In tutti i casi è necessario registrarlo come evento di sicurezza.

    
risposta data 28.10.2011 - 09:56
fonte
4

Di solito raccomando che tutte le eccezioni e gli errori mostrino una pagina di errore standard, e non dovrebbe rivelare il motivo per cui l'errore / eccezione si è verificato - o quale sia stato l'errore. Registrare l'errore e fornire all'utente il numero di transazione del registro.

La ragione per cui non vorrei rivelare cosa è successo, cioè questa azione è stata rifiutata a causa di un potenziale attacco CSRF, è che l'attaccante ottenga informazioni su come il sito protegge da un simile attacco. (Ovviamente nel caso specifico di CSRF ciò è rivelato dalla presenza di token, ma credo che non si dovrebbero rivelare più informazioni di quanto assolutamente necessario in ogni caso)

    
risposta data 28.10.2011 - 09:24
fonte
1

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.

    
risposta data 05.11.2011 - 06:03
fonte

Leggi altre domande sui tag