Qual è stata la motivazione dietro l'introduzione delle richieste di verifica preliminare?
Sono state introdotte richieste di verifica preliminare in modo che un browser potesse essere sicuro di avere a che fare con un server compatibile con CORS prima di inviare determinate richieste. Tali richieste sono state definite come potenzialmente pericolose (che cambiano lo stato) e nuove (non possibili prima del CORS a causa della stessa politica sull'origine ). L'uso delle richieste di verifica preliminare significa che i server devono attivare (rispondendo correttamente alla verifica preliminare) ai nuovi tipi di richieste potenzialmente pericolose rese possibili da CORS.
Questo è il significato di questa parte della specifica : "Per proteggere le risorse dalle richieste di origine incrociata che non potrebbero provenire da determinati agenti utente prima dell'esistenza di questa specifica, viene effettuata una richiesta di verifica preliminare per garantire che la risorsa sia a conoscenza di questa specifica".
Puoi farmi un esempio?
Immaginiamo che un utente del browser abbia effettuato l'accesso al proprio sito bancario all'indirizzo A.com
. Quando accedono al malware B.com
, quella pagina include alcuni Javascript a cui tenta di inviare una DELETE
richiesta A.com/account
. Poiché l'utente ha effettuato l'accesso A.com
, tale richiesta, se inviata, includerebbe i cookie che identificano l'utente.
Prima di CORS, la stessa politica di origine del browser gli avrebbe impedito di inviare questa richiesta. Ma poiché lo scopo di CORS è quello di rendere possibile questo tipo di comunicazione tra origini, non è più appropriato.
Il browser potrebbe semplicemente inviare il DELETE
e lasciare che il server decida come gestirlo. E se A.com
non fosse a conoscenza del protocollo CORS? Potrebbe andare avanti ed eseguire il pericoloso DELETE
. Si potrebbe presumere che, a causa della stessa politica di origine del browser, non sia mai stato in grado di ricevere una simile richiesta, e quindi potrebbe non essere mai stato indurito contro tale attacco.
Per proteggere tali server non compatibili con CORS, quindi, il protocollo richiede al browser di inviare prima una richiesta di verifica preliminare . Questo nuovo tipo di richiesta è qualcosa a cui solo i server compatibili con CORS possono rispondere correttamente, consentendo al browser di sapere se è sicuro o meno inviare l'effettivo DELETE
.
Perché tutte queste storie sul browser, l'attaccante non può semplicemente inviare una DELETE
richiesta dal proprio computer?
Certo, ma tale richiesta non includerà i cookie dell'utente. L'attacco che questo ha lo scopo di prevenire si basa sul fatto che il browser invierà cookie (in particolare, informazioni di autenticazione per l'utente) per l'altro dominio insieme alla richiesta.
Che suona come Cross-Site Request Forgery , in cui un modulo sul sito B.com
lattina POST
per A.com
con i cookie degli utenti e fare danni.
Giusto. Un altro modo per dirlo è che le richieste di verifica preliminare sono state create in modo da non aumentare la superficie di attacco CSRF per server non compatibili con CORS.
Ma osservando i requisiti per le richieste "semplici" che non richiedono preflight, vedo che POST
è ancora consentito. Ciò può cambiare stato ed eliminare i dati proprio come un DELETE
!
È vero! CORS non protegge il tuo sito dagli attacchi CSRF. Inoltre, senza CORS non sei protetto dagli attacchi CSRF. Lo scopo delle richieste di verifica preliminare è solo quello di limitare l'esposizione CSRF a ciò che esisteva già nel mondo pre-CORS.
Sospiro. OK, accetto a malincuore la necessità di richieste di verifica preliminare. Ma perché dobbiamo farlo per ogni risorsa (URL) sul server? Il server gestisce CORS oppure no.
Sei sicuro di questo? Non è raro che più server gestiscano le richieste per un singolo dominio. Ad esempio, è possibile che le richieste A.com/url1
vengano gestite da un tipo di server e le richieste da A.com/url2
gestire da un diverso tipo di server. In genere non è il caso che il server che gestisce una singola risorsa possa offrire garanzie di sicurezza su tutte le risorse di quel dominio.
Belle. Scendiamo a compromessi. Creiamo una nuova intestazione CORS che consente al server di indicare esattamente per quali risorse può parlare, in modo da evitare ulteriori richieste di verifica preliminare a tali URL.
Buona idea! In effetti, l'intestazione è Access-Control-Policy-Path
stata proposta proprio per questo scopo. Alla fine, però, è stato lasciato fuori dalle specifiche, a quanto pare perché alcuni server hanno implementato erroneamente la specifica URI in modo tale che le richieste a percorsi che sembravano sicuri per il browser non sarebbero in effetti sicure sui server rotti.
È stata una decisione prudente che ha dato la priorità alla sicurezza rispetto alle prestazioni, consentendo ai browser di implementare immediatamente le specifiche CORS senza mettere a rischio i server esistenti? O era miope condannare Internet a sprecare larghezza di banda e raddoppiare la latenza solo per sistemare i bug in un determinato server in un determinato momento?
Le opinioni sono diverse.
Bene, almeno i browser memorizzeranno nella cache il preflight per un singolo URL?
Sì. Anche se probabilmente non per molto tempo. Nei browser WebKit il tempo massimo di cache di verifica preliminare è attualmente di 10 minuti .
Sospiro. Bene, se so che i miei server sono compatibili con CORS e quindi non necessitano della protezione offerta dalle richieste di verifica preliminare, c'è un modo per evitarli?
La tua unica vera opzione è assicurarti di soddisfare i requisiti per le richieste "semplici". Ciò potrebbe significare tralasciare le intestazioni personalizzate che altrimenti includeresti (come X-Requested-With
), mentendo sul Content-Type
, o altro.
Qualunque cosa tu faccia, devi assicurarti di avere adeguate protezioni CSRF in atto poiché la specifica CORS non affronta il rifiuto di richieste "semplici", incluso il non sicuro POST
. Come afferma la specifica : "le risorse per le quali le richieste semplici hanno un significato diverso dal recupero devono proteggersi dalla falsificazione di richieste tra siti".