2013-10-11 8 views
30

Si dice che invece di aggiungere tutti i domini a CORS, si dovrebbe aggiungere solo un insieme di domini. Tuttavia a volte non è banale aggiungere un set di domini. Per esempio. se voglio esporre pubblicamente un'API, allora per ogni dominio che desidera effettuare una chiamata a tale API, dovrei essere contattato per aggiungere quel dominio all'elenco dei domini consentiti.Implicazioni sulla sicurezza dell'aggiunta di tutti i domini a CORS (Access-Control-Allow-Origin: *)

Mi piacerebbe fare un compromesso consapevole tra le implicazioni di sicurezza e meno lavoro.

Gli unici problemi di sicurezza che vedo sono gli attacchi DoS attacks e CSRF. Gli attacchi CSRF possono essere già raggiunti con elementi IMG e elementi FORM. Gli attacchi DoS relativi a CORS possono essere risolti bloccando le richieste sull'intestazione del referrer.

Mi mancano le implicazioni sulla sicurezza?


=== === Modifica

  • Si presume che l'intestazione Access-Control-Allow-Credentials non è impostato
  • So come aggiungere un determinato elenco di domini "accesso CORS" e Sono quindi interessato solo alle implicazioni di sicurezza dell'aggiunta di tutti i domini "accesso CORS"
+0

si può già eseguire il ping del URL con i tag img o iframe, CORS lascia solo ajax recuperare l'url. – dandavis

+0

La modifica modifica drasticamente le implicazioni. Non consentendo alcuna richiesta autenticata, ciò significa che gli endpoint che si spera di esporre tramite CORS sono necessariamente limitati a funzioni "pubbliche". Tali endpoint molto probabilmente non risentirebbero affatto di avere Access-Control-Allow-Origin: *, principalmente perché non è possibile eseguire attacchi CSRF a un endpoint pubblico. –

+0

Non penso sia possibile nemmeno usare 'Access-Control-Allow-Origin: *' insieme a 'Access-Control-Allow-Credentials: true' Vedere https://developer.mozilla.org/en- US/docs/Web/HTTP/Access_control_CORS # Access-Control-Allow-Origin e https://www.w3.org/TR/cors/#resource-requests – seanf

risposta

1

Tranne quello di csauve, nessuna delle risposte risponde alla mia domanda originale.

Per rispondere alla mia domanda; Sembra che finché Access-Control-Allow-Credentials non è impostato, non ci sono problemi di sicurezza.

(Il che mi fa chiedere il motivo per cui le specifiche richiede verifica preliminare quando Access-Control-Allow-Credentials non è impostato?)

-1

Best Practice consiste nel controllare prima il dominio della richiesta in arrivo e quindi generare l'intestazione della risposta. A seconda che questo dominio possa inviare richieste, lo aggiungi (solo questo) all'intestazione di risposta Access-Control-Allow-Origin.

Afaik, non è nemmeno possibile aggiungere più di un dominio a questa intestazione. Quindi è uno * o un dominio specifico e mi sarebbe sempre preferirei non aggiungere *

+8

La tua risposta non spiega le implicazioni sulla sicurezza di consentire tutti i domini – brillout

9

è possibile inviare più di una, come:

Access-Control-Allow-Origin: http://my.domain.com https://my.domain.com http://my.otherdomain.com 

ma vorrei consigliare contro di essa. Invece, mantieni una whitelist dei domini consentiti. Diciamo:

allowed = [ "X", "Y", "A.Z" ]; 

Poi, se si riceve una richiesta da X si risponde con:

Access-Control-Allow-Origin: X 

Se si riceve una richiesta da A.Z si risponde con:

Access-Control-Allow-Origin: A.Z 

Se si ottiene una richiesta da un dominio che non è consentito, rispondere con un errore o nessuna politica CORS.

Tutte le richieste XHR invieranno un'intestazione Origin, quindi utilizzarlo. E hai solo bisogno di inviare le intestazioni delle politiche CORS per la richiesta OPTIONS, non la richiesta GET/POST/HEAD che segue.


Il problema principale che vedo è che si espongono tutti i domini.Forse hai un dominio amministratore sicuro come: https://admin.mydomain.com, o forse hai un sito web di prodotto che non è ancora pronto per il lancio. Non vuoi includere tutto ciò che non è assolutamente necessario per la richiesta in questione.

E * è semplicemente estremamente pigro.


+6

La tua risposta non spiega le implicazioni sulla sicurezza di consentire tutti i domini – brillout

+1

Penso che l'hai già trattata nella tua domanda. Se vuoi una risposta autorevole ti consiglierei di mettere una taglia. – Halcyon

+1

Nota che, se lo fai, dovresti includere anche l'intestazione 'Vary: Origin' per indicare che le intestazioni di risposta dipendono dall'intestazione' Origin' della richiesta. – augurar

4

CORS è su come ottenere il contenuto di nuovo, non solo effettua la richiesta. Quando ottieni una risorsa tramite un tag img o script, puoi ingannare il browser di qualcuno per creare una richiesta di stile CSRF. Questo è normale e puoi proteggerlo con un normale token CSRF.

Con CORS abilitato su tutti i domini, ora è possibile fare in modo che javascript su un sito in attacco effettui una richiesta e recuperi il contenuto, invadendo la privacy.

Esempio:

Immaginate la schiena permette CORS per tutti i domini. Ora faccio un sito web che fa una richiesta a yourimaginarybank.com/balance

Una richiesta IMG non farebbe nulla, perché il mio javascript non può ottenere ciò che era nell'html di quella pagina sul sito web della vostra banca. Ora che hanno attivato CORS, il javascript sul mio sito riporta effettivamente una pagina HTML con il tuo saldo su di esso e la salva sul mio server. Non solo posso fare una richiesta GET come prima, ma ora posso vedere cosa c'è dentro. Questo è un enorme problema di sicurezza.

Come risolvere il problema senza aggiungere una grande lista alle intestazioni? Ogni richiesta CORS viene effettuata con l'intestazione Origin. La soluzione migliore è probabilmente quella di leggere l'intestazione Origin, quindi interrogare un database per vedere se è nella whitelist come suggerito da Fritz nella sua risposta.

+5

Il punto presume che i cookie della banca vengano inviati insieme alla richiesta che, di default, non è il caso. Per i cookie da inviare è necessario impostare un'intestazione aggiuntiva '' Access-Control-Allow-Credentials'' su '' true'' – brillout

20

Richiesta tra siti Gli attacchi di contraffazione sono di gran lunga la preoccupazione principale degli indirizzi Access-Control-Allow-Origin.

Ryan ha sicuramente ragione per quanto riguarda il recupero dei contenuti. Tuttavia, a proposito di fare la richiesta c'è altro da dire qui. Molti siti Web ora forniscono servizi Web RESTful che espongono una vasta gamma di funzionalità che potrebbero comportare modifiche significative nel back-end. Molto spesso, questi servizi RESTful devono essere richiamati con una richiesta XHR (ad esempio AJAX) (probabilmente con un "Single Page Application" come front-end). Se un utente ha una sessione attiva che concede l'accesso a questi servizi quando visita un sito di terze parti malintenzionato, quel sito potrebbe provare a richiamare quegli endpoint REST dietro le quinte, trasmettendo valori che potrebbero compromettere l'utente o il sito. A seconda di come sono definiti i servizi REST, ci sono vari modi per proteggersi da questo.

Nel caso specifico di servizi web REST per una singola pagina App, è possibile dettare che tutte le richieste per gli endpoint backend REST sono realizzati con XHR e di rifiutare qualsiasi richiesta non XHR. È possibile dettare questo controllando la presenza di un'intestazione di richiesta personalizzata (qualcosa come X-Requested-With di jQuery). Solo le richieste di tipo XHR possono impostare queste intestazioni; semplici richieste GET e POST da moduli e risorse incorporate non possono. Infine, il motivo per cui vogliamo dettare le richieste XHR ci riporta alla domanda originale: le richieste XHR sono soggette alle regole CORS.

Se si autorizza Access-Control-Allow-Origin: *, qualsiasi sito può effettuare qualsiasi richiesta AJAX per conto dell'utente per gli endpoint REST. Se gli endpoint REST implicano qualsiasi tipo di dati sensibili o consentono la persistenza dei dati, questa è una vulnerabilità di sicurezza inaccettabile. Invece, impone richieste solo XHR come ho descritto e definito una whitelist di origini autorizzate a fare quelle richieste.

Vale la pena sottolineare che se gli endpoint REST non espongono alcuna informazione sensibile o se non consentono all'utente di apportare modifiche persistenti ai dati, quindi Access-Control-Allow-Origin: * potrebbe essere appropriato decisione. Google Maps, ad esempio, fornisce viste di sola lettura nei dati della mappa pubblica; non vi è alcun motivo per limitare i siti di terze parti che potrebbero voler invocare tali servizi.

+7

Il tuo punto presume che i cookie siano inviati insieme alla richiesta che di default non è il caso . Per i cookie da inviare è necessario impostare un'intestazione aggiuntiva '' Access-Control-Allow-Credentials'' su '' true'' – brillout

+0

Se sei corretto, l'attacco CSRF dipende dall'intestazione impostata. Non penso che ciò diminuisca il mio punto, comunque. Se stai lavorando con endpoint che forniscono dati sensibili o aggiornabili e stai tentando di fare qualcosa con CORS, allora devi avere questa intestazione. Una volta impostato, dovrai quindi preoccuparti di quali domini richiedono questi endpoint autenticati e prendere le misure che descrivo per evitare che richieste non XHR possano richiamarle. Se non esponi la funzionalità privata, probabilmente non c'è ragione per non utilizzare semplicemente Access-Control-Allow-Origin: *. –

+2

Non hai bisogno di biscotti se usi '' localStorage'' – brillout

5

Vecchia domanda, ma un sacco di risposte negative qui, quindi devo aggiungere il mio.

Se non si imposta Access-Control-Allow-Credentials e si esegue l'autenticazione senza cookie (ovvero il chiamante fornisce un'intestazione Autorizzazione al portatore), non è necessario inserire in whitelist le origini. Basta richiamare l'origine di nuovo in Access-Control-Allow-Origin.

Un'API REST ben strutturata può essere richiamata in modo sicuro da qualsiasi origine.

+1

Same POV. Cioè sembra che finché Access-Control-Allow-Credentials non è impostato, non ci sono problemi di sicurezza. Questo mi rende chiedo perché la specifica richiede preflight quando 'Access-Control-Allow-credentials' non è impostato. – brillout