Comprendere CSRF in profondità
Fornisce un'esplorazione approfondita degli attacchi Cross-Site Request Forgery (CSRF), spiegando la loro meccanica, dimostrando esempi e dettagliando vari metodi di prevenzione per migliorare la sicurezza delle applicazioni web.
Quando si lavora nello sviluppo web, soprattutto con i cookie, sentiamo spesso frasi come "questa impostazione aiuta a prevenire il CSRF". Tuttavia, molte persone hanno solo un'idea vaga di cosa significhi veramente "CSRF".
Oggi, approfondiremo il CSRF (Cross-Site Request Forgery), una comune vulnerabilità della sicurezza web. Questo ci aiuterà a gestire i problemi legati al CSRF in modo più efficace.
Cos'è il CSRF?
Il CSRF (Cross-Site Request Forgery) è un tipo di attacco web dove gli attaccanti ingannano gli utenti autenticati facendo eseguire azioni non desiderate. In termini semplici, sono "hacker che fingono di essere utenti per eseguire azioni non autorizzate".
Come funziona il CSRF
Per comprendere il CSRF, dobbiamo afferrare alcuni concetti chiave:
Regola della stessa origine del browser
La regola della stessa origine è una funzione di sicurezza nei browser che limita il modo in cui un documento o script da un'origine può interagire con risorse da un'altra origine.
Un'origine consiste di un protocollo (come HTTP o HTTPS), nome di dominio e numero di porta. Ad esempio, https://example.com:443
è un'origine, mentre https://demo.com:80
è un'altra.
La regola della stessa origine limita l'accesso ai dati tra pagine di origini diverse, significando:
- JavaScript da un'origine non può leggere il DOM di un'altra origine
- JavaScript da un'origine non può leggere il Cookie, IndexedDB o localStorage di un'altra origine
- JavaScript da un'origine non può inviare richieste AJAX a un'altra origine (a meno che non si utilizzi CORS)
Tuttavia, per mantenere l'apertura e l'interoperabilità del Web (come il caricamento di risorse da CDN o l'invio di richieste a API di terze parti per logging), la regola della stessa origine non limita le richieste di rete cross-origin:
- Le pagine possono inviare richieste GET o POST a qualsiasi origine (come caricamento di immagini o invio di moduli)
- Risorse da qualsiasi origine possono essere incluse (come tag
<script>
,<img>
,<link>
,<iframe>
)
Meccanismo automatico di invio dei cookie
Il meccanismo automatico di invio dei cookie è una funzione importante dei browser. Quando un browser invia una richiesta a un dominio, allega automaticamente tutti i cookie per quel dominio. Questo processo è automatico e non richiede alcun codice JavaScript o interazione dell'utente.
Questo meccanismo consente ai siti web di ricordare facilmente lo stato di accesso degli utenti perché ogni richiesta trasporta automaticamente le informazioni di identità dell'utente.
Grassetto
Ad esempio, quando fai il login su un sito web bancario (bank.com
) e ottieni un cookie di identità, poi quando clicchi per visualizzare il tuo estratto conto, il browser trova automaticamente tutti i cookie corrispondenti a bank.com
e li allega alla richiesta dell'estratto conto. Il server della banca può quindi identificarti dal backend e restituire le informazioni del tuo estratto conto.
Fasi dell'attacco CSRF
-
L'utente fa il login al sito web target (come un sito bancario) e ottiene un cookie di autenticazione. Questo passaggio utilizza il meccanismo automatico di invio dei cookie. Dopo che il sito bancario imposta un cookie di autenticazione dell'identità, il browser allegherà automaticamente questo cookie a ogni richiesta inviata a quel sito.
-
Senza fare logout, l'utente visita un sito web malevolo. A questo punto, a causa della regola della stessa origine, il sito malevolo non può leggere o modificare direttamente il cookie del sito bancario. Questo protegge le informazioni di identità dell'utente dal furto diretto.
-
Il sito malevolo include una richiesta al sito target (come un'operazione di trasferimento). Anche se la regola della stessa origine limita l'accesso cross-origin, consente richieste di rete cross-origin, come richieste avviate tramite tag
<img>
,<form>
. Gli attaccanti sfruttano questa "falla". -
Il browser dell'utente invia automaticamente questa richiesta, insieme al cookie del sito target. Questo è il cuore dell'attacco CSRF. Sfrutta sia la regola della stessa origine che consente richieste cross-origin sia il meccanismo automatico di invio dei cookie (anche le richieste attivate da siti malevoli porteranno i cookie corrispondenti al dominio).
-
Il sito target riceve la richiesta, verifica che il cookie sia valido ed esegue l'operazione. Il server non può determinare se questa richiesta proviene da un'azione legittima dell'utente perché il cookie allegato è valido.
Esempio di attacco CSRF
Illustriamo come avviene un attacco CSRF con un esempio specifico. Useremo un sito bancario fittizio bank.com
come esempio.
Prima, l'utente visita https://bank.com
e fa il login sul suo account.
Dopo un login riuscito, il server imposta un cookie di autenticazione, ad esempio:
L'utente esegue un'operazione di trasferimento sul sito bancario, ad esempio trasferendo 1000 $ a Alice. Questa operazione potrebbe inviare una richiesta come questa:
Ora, supponiamo che un attaccante crei un sito malevolo https://evil.com
contenente il seguente HTML:
Quando l'utente clicca sul link https://evil.com
senza aver fatto logout dal suo account bancario, perché è già connesso a bank.com
, il browser dispone di un cookie session_id
valido.
Dopo che la pagina malevola si carica, invia automaticamente il modulo nascosto, inviando una richiesta di trasferimento a https://bank.com/transfer
.
Il browser dell'utente allega automaticamente il cookie bank.com
a questa richiesta. Il server di bank.com
riceve la richiesta, verifica che il cookie sia valido, e quindi esegue questa operazione di trasferimento non autorizzata.
Metodi comuni per prevenire attacchi CSRF
Ecco diversi metodi comunemente utilizzati per difendersi dagli attacchi CSRF. Spiegheremo in dettaglio il principio di ciascun metodo e come previene efficacemente gli attacchi CSRF:
Usare i token CSRF
I token CSRF sono uno dei metodi più comuni ed efficaci per difendersi dagli attacchi CSRF. Ecco come funziona:
- Il server genera un token unico e imprevedibile per ogni sessione.
- Questo token è incorporato in tutti i moduli per operazioni sensibili.
- Quando l'utente invia un modulo, il server verifica la validità del token.
Poiché il token CSRF è un valore unico legato alla sessione dell'utente, e l'attaccante non può conoscere o indovinare questo valore (poiché è diverso per ogni sessione), anche se l'attaccante inganna l'utente a inviare una richiesta, la richiesta sarà respinta dal server a causa della mancanza di un token CSRF valido.
Esempio di implementazione:
Sul lato server (usando Node.js e Express):
In JavaScript frontend:
Controllo dell'intestazione Referer
L'intestazione Referer
contiene l'URL della pagina che ha avviato la richiesta. Controllando l'intestazione Referer
, il server può determinare se la richiesta proviene da una fonte legittima.
Poiché gli attacchi CSRF di solito provengono da domini diversi, l'intestazione Referer
mostrerà il nome di dominio dell'attaccante. Verificando se il Referer
è il valore atteso, le richieste da fonti sconosciute possono essere bloccate.
Tuttavia, è importante notare che questo metodo non è del tutto affidabile, poiché alcuni browser potrebbero non inviare l'intestazione Referer, e gli utenti possono disabilitare l'intestazione Referer tramite le impostazioni del browser o i plugin.
Esempio di implementazione:
Uso dell'attributo SameSite nei cookie
SameSite
è un attributo dei cookie utilizzato per controllare se i cookie sono inviati con richieste cross-site. Ha tre valori possibili:
Strict
: I cookie sono inviati solo in richieste same-site.Lax
: I cookie sono inviati in richieste same-site e navigazioni a livello superiore.None
: I cookie sono inviati in tutte le richieste cross-site (devono essere usati con l'attributoSecure
).
Quando SameSite
è impostato su Strict
, può prevenire completamente i siti web di terze parti dall'inviare cookie, prevenendo così efficacemente gli attacchi CSRF.
Se SameSite
è impostato su Lax
, protegge le operazioni sensibili consentendo alcuni casi d'uso cross-site comuni (come entrare in un sito web da link esterni).
Esempio di implementazione:
Uso di intestazioni di richiesta personalizzate
Per le richieste AJAX, possono essere aggiunte intestazioni di richiesta personalizzate. A causa delle restrizioni della regola della stessa origine, gli attaccanti non possono impostare intestazioni personalizzate in richieste cross-origin. Il server può controllare la presenza di questa intestazione personalizzata per verificare la legittimità della richiesta.
Esempio di implementazione:
Sul frontend:
Sul lato server:
Verifica doppia dei cookie
La verifica doppia dei cookie è una tecnica di difesa CSRF efficace. Il suo principio di base è che il server genera un token casuale, lo imposta sia come cookie sia lo incorpora nella pagina (di solito come campo nascosto di un modulo). Quando il browser invia una richiesta, include automaticamente il cookie, mentre il JavaScript della pagina invia il token come parametro di richiesta. Il server verifica poi se il token nel cookie corrisponde al token nei parametri di richiesta.
Anche se gli attaccanti possono includere il cookie del sito target in richieste cross-site, non possono leggere o modificare il valore del cookie, né possono accedere o modificare il valore del token nella pagina. Richiedendo che la richiesta includa token sia dal cookie sia dai parametri, si garantisce che la richiesta provenga da una fonte con permesso di leggere il cookie, difendendo così efficacemente contro gli attacchi CSRF.
Uso della riautenticazione per operazioni sensibili
Per operazioni particolarmente sensibili (come cambiare password o effettuare trasferimenti di grandi somme), gli utenti possono essere richiesti di riautenticarsi. Questo fornisce agli utenti un ulteriore punto di controllo della sicurezza. Anche se un utente riesce a iniziare un attacco CSRF, non può superare il passaggio di riautenticazione.
Suggerimenti per l'implementazione:
- Prima di eseguire operazioni sensibili, reindirizzare a una pagina di autenticazione separata.
- Su questa pagina, richiedere all'utente di inserire la sua password o altre informazioni di verifica dell'identità.
- Dopo che la verifica viene superata, generare un token una tantum e usarlo in operazioni sensibili successive.
Sommario
Attraverso questa discussione approfondita, speriamo tu abbia ora una comprensione più completa degli attacchi CSRF. Non abbiamo solo imparato come funziona il CSRF ma anche esplorato varie misure di difesa efficaci. Tutti questi metodi possono migliorare efficacemente la sicurezza delle applicazioni web.
Speriamo che questa conoscenza ti aiuti a gestire meglio i problemi legati al CSRF nel tuo sviluppo quotidiano e a costruire applicazioni web più sicure.