Domanda:
Devo usare la protezione CSRF sugli endpoint dell'API Rest?
Conor Mancone
2017-08-03 23:41:43 UTC
view on stackexchange narkive permalink

Nota rapida: questo non è un duplicato della protezione CSRF con intestazioni personalizzate (e senza il token di convalida) nonostante alcune sovrapposizioni. Quel post discute come eseguire la protezione CSRF sugli endpoint Rest senza discutere se è effettivamente necessario. In effetti, molte domande CSRF / Rest che ho letto su questo sito parlano della protezione degli endpoint tramite token CSRF senza discutere effettivamente se sia necessario o meno. Da qui questa domanda.

La protezione CSRF è necessaria per gli endpoint dell'API Rest?

Ho visto molte discussioni sulla protezione degli endpoint REST dagli attacchi CSRF, ma avendo riflettuto molto sull'argomento, sono certo che i token CSRF su un endpoint REST garantiscano zero protezione aggiuntiva. In quanto tale, abilitare la protezione CSRF su un endpoint REST introduce semplicemente del codice inutile nella tua applicazione e penso che dovrebbe essere saltato. Potrei perdere qualcosa però, da qui questa domanda. Penso che aiuterà a tenere a mente perché la protezione CSRF è necessaria in primo luogo e i vettori di attacco da cui protegge:

Perché CSRF?

Si riduce davvero alla capacità del browser di presentare automaticamente le credenziali di accesso per qualsiasi richiesta inviando cookie. Se un ID di sessione è memorizzato in un cookie, il browser lo invierà automaticamente insieme a tutte le richieste che risalgono al sito Web originale. Ciò significa che un utente malintenzionato non deve effettivamente conoscere i dettagli di autenticazione per eseguire un'azione come utente vittima. Piuttosto, l'aggressore deve solo indurre il browser della vittima a fare una richiesta e le credenziali per autenticare la richiesta verranno eseguite gratuitamente.

Inserisci un'API REST

Gli endpoint dell'API Rest hanno una differenza molto importante rispetto ad altre richieste: sono specificamente senza stato e non dovrebbero mai accettare / utilizzare dati da un cookie o da una sessione. Di conseguenza, un'API REST che si attiene allo standard è automaticamente immune a tale attacco. Anche se un cookie fosse inviato dal browser, qualsiasi credenziale associata al cookie verrebbe completamente ignorata. L'autenticazione delle chiamate a un'API REST viene eseguita in modo completamente diverso. La soluzione più comune è avere una sorta di chiave di autenticazione (un token OAuth o simile) che viene inviata nell'intestazione da qualche parte o possibilmente nel corpo della richiesta stesso.

Poiché l'autenticazione è specifica dell'applicazione, e poiché il browser stesso non sa quale sia il token di autenticazione, non c'è modo per un browser di fornire automaticamente le credenziali di autenticazione anche se è in qualche modo indotto a visitare l'endpoint API. Di conseguenza, un endpoint REST senza cookie è completamente immune dagli attacchi CSRF.

O mi sto perdendo qualcosa?

Alcune API REST limitano le chiamate per ip, che potrebbe essere un caso limite in cui potrebbe avere senso implementare una protezione csrf.
Grazie per il contributo @Xavier59.Ti dispiace chiarire: perché la limitazione della frequenza richiederebbe la protezione CSRF?
Quindi non sono sicuro che questo sia necessariamente applicabile al tuo caso, ma supponiamo che tu usi Google come fornitore di oauth.Il tuo utente accede a un sito dannoso che utilizza anche Google come provider oauth.Il sito dannoso potrebbe utilizzare il token dell'utente (ish, a seconda delle impostazioni del client e simili) per il tuo sito.Vedi qui per ulteriori informazioni: https://spring.io/blog/2011/11/30/cross-site-request-forgery-and-oauth2
@ConorMancone Se il sito "A" ha un'API REST che limita la chiamata per ip a 1 / secondo, un utente malintenzionato potrebbe ingannare Bob per andare sul sito "B" che invia decine di richieste al secondo.Potrebbe comportare l'esclusione dell'ip di Bob da questa API REST o impedirgli di utilizzare correttamente l'API REST.Sono d'accordo che sia un po 'inverosimile ma non del tutto impossibile.
@Xavier59 Ciò equivale in qualche modo a tentare di eseguire attacchi DDoS a un sito Web ottenendo un tag img con il sito Web come attributo di origine su un sito Web ad alto traffico.Non è necessariamente inverosimile.Detto questo, non vedo perché i token CSRF farebbero qualcosa per mitigare un simile attacco.
Grazie @JesseKeilson.Dovrò digerire quello.Solo perché un vettore di attacco è sicuro non significa che non sia pericoloso!
@ConorMancone CSRF mitigherebbe questo problema non consentendo (e contando) la richiesta con un token csrf non associato all'ip corretto.Pertanto, Bob ip non verrebbe inserito nella lista nera dall'utilizzo del resto api.Spero tu abbia capito il mio punto.
@JesseKeilson Il collegamento in questione era incentrato sugli attacchi CSRF contro i server di convalida OAUTH.E 'stata una lettura interessante.Il riepilogo generale è qualcosa che ho imparato prima: in termini di flusso di lavoro generale, OAuth2 è sorprendentemente insicuro.Per essere chiari, mi riferisco specificamente al processo di emissione dei token OAuth2.L'utilizzo di questi gettoni è una questione diversa ed è generalmente molto più semplice.
Sette risposte:
#1
+173
Conor Mancone
2017-08-04 18:25:29 UTC
view on stackexchange narkive permalink

Inizialmente non stavo mirando a un'auto-risposta, ma dopo ulteriori letture ho trovato quella che credo essere una risposta completa che spiega anche perché alcuni potrebbero essere ancora interessati alla protezione CSRF sugli endpoint REST.

Nessun cookie = Nessun CSRF

È davvero così semplice. I browser inviano cookie insieme a tutte le richieste. Gli attacchi CSRF dipendono da questo comportamento. Se non si utilizzano i cookie e non si fa affidamento sui cookie per l'autenticazione, non c'è assolutamente spazio per gli attacchi CSRF e non c'è motivo di inserire la protezione CSRF. Se disponi di cookie, soprattutto se li utilizzi per l'autenticazione, è necessaria la protezione CSRF. Se tutto quello che vuoi sapere è "Ho bisogno della protezione CSRF per il mio endpoint API?" puoi fermarti qui e partire con la tua risposta. Altrimenti, il diavolo è nei dettagli.

h / t to paj28: sebbene i cookie siano il vettore di attacco principale per gli attacchi CSRF, sei anche vulnerabile se utilizzi HTTP / Basic autenticazione. Più in generale, se il browser è in grado di trasmettere automaticamente le credenziali di accesso per la tua app, allora CSRF è importante. Nella mia esperienza i cookie sono la tecnologia più comune sfruttata per realizzare CSRF, ma ci sono alcuni altri metodi di autenticazione che vengono utilizzati che possono provocare la stessa vulnerabilità.

REST = Stateless

Se chiedi a qualcuno "cos'è REST" otterrai una varietà di risposte che discutono una varietà di proprietà diverse. Puoi vedere tanto perché qualcuno ha posto quella domanda su stack overflow: https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming

Una proprietà di REST su cui ho sempre fatto affidamento è che è apolide. L'applicazione stessa ha lo stato del corso. Se non puoi memorizzare i dati in un database da qualche parte, la tua applicazione sarà piuttosto limitata. In questo caso, però, stateless ha un significato molto specifico e importante: le applicazioni REST non tengono traccia dello stato per l'applicazione lato client . Se stai utilizzando sessioni, stai (quasi certamente) tenendo traccia dello stato lato client e non sei un'applicazione completa di REST. Quindi un'applicazione che utilizza sessioni (soprattutto per gli accessi) tracciate tramite cookie non è un'applicazione REST-full (IMO) ed è certamente vulnerabile agli attacchi CSRF, anche se altrimenti sembra un'applicazione REST.

Penso che valga la pena notare che uno dei motivi per cui l'apolidia lato client è importante per le applicazioni REST è che anche la capacità degli intermediari di memorizzare nella cache le risposte è una parte desiderabile del paradigma REST. Finché l'applicazione tiene traccia dello stato lato client, la memorizzazione nella cache non è possibile.

Rest ≠ Cookieless

Per questi motivi, inizialmente ho supposto che un un'applicazione REST completamente conforme non avrebbe mai bisogno di sessioni, non avrebbe mai bisogno di cookie e quindi non avrebbe mai bisogno della sicurezza CSRF. Tuttavia, c'è almeno un caso d'uso che potrebbe comunque preferire i cookie: accessi persistenti.

Considera una tipica applicazione web lato client (in questo caso browser, non mobile). Si inizia effettuando l'accesso, che utilizza un'API REST per convalidare le credenziali dell'utente e in cambio viene fornito un token per autorizzare richieste future. Per le applicazioni a pagina singola, puoi semplicemente mantenere quel token in memoria, ma così facendo disconnetterai l'utente se chiuderà la pagina. Di conseguenza, sarebbe bene mantenere lo stato da qualche parte che può durare più a lungo di una singola sessione del browser. L'archiviazione locale è un'opzione, ma è anche vulnerabile agli attacchi XSS: un attacco XSS riuscito può far sì che l'aggressore afferri i tuoi token di accesso e li invii all'attaccante per utilizzarli a sua discrezione.

Per questo motivo, ho visto alcuni suggerire di utilizzare i cookie per memorizzare i token di accesso. Con un cookie è possibile impostare il flag solo http, che impedisce all'applicazione di leggere il cookie dopo che è stato impostato. Di conseguenza, in caso di un attacco XSS, l'aggressore può comunque effettuare chiamate per tuo conto, ma non può abbandonare il token di autorizzazione tutti insieme. Questo utilizzo dei cookie non viola direttamente il requisito di apolidia di REST perché il server non sta ancora monitorando lo stato lato client. Sta solo cercando le credenziali di autenticazione in un cookie, piuttosto che nell'intestazione.

Lo dico perché è potenzialmente un motivo legittimo per utilizzare i cookie con un'API REST, sebbene spetti ovviamente a una determinata applicazione per bilanciare i vari problemi di sicurezza e usabilità. Personalmente tenterei di evitare di utilizzare i cookie con le API REST, ma potrebbero esserci comunque dei motivi per utilizzarli. Ad ogni modo, la risposta generale è semplice: se stai utilizzando i cookie (o altri metodi di autenticazione che il browser può eseguire automaticamente), allora hai bisogno della protezione CSRF. Se non stai utilizzando i cookie, non lo fai.

Sei praticamente perfetto.L'autenticazione di base HTTP può essere vulnerabile a CSRF così come l'autenticazione basata su IP e altri.Al contrario, i cookie possono essere sicuri se è solo un client su misura che utilizza il servizio, non un browser.Questo probabilmente non influisce sulle tue decisioni, ma vale la pena tenerlo a mente.Ho trovato persone che cercano di definire ciò che è "corretto REST" come una delle discussioni meno costruttive in ambito IT.In termini pratici, la maggior parte dei servizi necessita di autenticazione e le sessioni sono un modo ragionevole per farlo.
Grazie @paj28.L'autenticazione di base HTTP è un ottimo punto da menzionare.È molto meno comune, penso (motivo per cui ho dimenticato di menzionarlo), ma è bene menzionare le eccezioni quando stai cercando di trovare una risposta esauriente.
Non ho ottenuto il terzo punto, ho ancora bisogno della protezione CSRF se memorizzo il token in un cookie di sessione?
@HFA Se si utilizzano i cookie, soprattutto per l'autenticazione, è necessaria la protezione CSRF.Non importa cosa stai memorizzando nel cookie: se il contenuto di un cookie viene utilizzato per autenticare i tuoi utenti con la tua app, allora CSRF è necessario perché il browser allega automaticamente i cookie a tutte le richieste al tuo sito.
Memorizzo il token di autenticazione all'interno di un cookie con durata della sessione e utilizzo il contenuto di quel cookie per intercettare ogni richiesta http e aggiungere un'intestazione di autorizzazione alle richieste http, conta anche questo?;)
@HFA: Per utilizzare il contenuto di quel cookie è necessario che il cookie NON sia HttpOnly (ovvero accessibile da JS).In questo modo ti esponi potenzialmente a XSS, come se stessi usando l'archiviazione locale.Inoltre, se il tuo server _accetta_ il cookie come mezzo di autenticazione, sei aperto anche per CSRF.Quindi usa l'archiviazione locale e assicurati di impedire XSS, i cookie hanno senso solo se il tuo server li accetta.
@BorisB.LocalStorage non ha capacità di durata della sessione, quindi utilizzo un cookie di sessione impostato da javascript nella macchina dell'utente per memorizzare il token.Utilizzo un'intestazione di autorizzazione per l'autenticazione e non un cookie.
ciao ... come se mi fossi già autenticato e avessi i `cookies`, per fare qualcosa come` Brute Force`?
HTTP è in realtà un protocollo senza stato.Il motivo per cui viene chiamato è perché 2 diverse richieste (connessioni) al server possono provenire da luoghi diversi, ma se il contenuto della richiesta è lo stesso, si otterrebbero più o meno gli stessi dati (se lo stato del server non è cambiato).Ecco perché HTTP è un ottimo protocollo per REST.I cookie HTTP vengono inviati anche nell'intestazione (il browser lo aggiunge automaticamente), mentre la maggior parte delle API REST lo prevede in un'altra intestazione come Autorizzazione.Sia che memorizzi il tuo token in cookie, localStorage o sessionStorage, uno script XSS avrà accesso ad esso, ma non un semplice attacco CSRF.
Sto usando localStorage per salvare accesstoken, è vulnerabile a CSRF?
@Shashidhara no.ma ora è un rischio XSS più elevato rispetto a un cookie httpOnly (è un compromesso, non dicendo che localStorage è negativo, solo un modello di minaccia diverso)
Un piccolo chiarimento: "Nessun cookie = Nessun CSRF" - Lo pensavo anch'io, ma con il supporto del browser nativo Kerberos / NTLM, (SPNEGO) un token Kerberos viene inviato a un insieme di domini autorizzati.Questi casi dovrebbero anche avere la protezione CSRF in quanto è essenzialmente la stessa di un cookie nel modo in cui "qualcosa che invia automaticamente qualcosa su richieste" quindi penso che se invii un modulo con destinazione come un endpoint API kerberizzato, mentre sei inla rete interna, anche qui c'è un rischio CSRF no?
Sì, anche secondo OWASP, non sono solo cookie, se hai NTLM / Kerberos, è necessario anche CSRF.https://www.owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery
Un altro su "Nessun cookie = Nessun CSRF": se si memorizza il token di sessione nell'URL (cattiva idea, ma succede), è facile indurre l'utente a inviare il modulo come con il token di sessione nei cookie.Ciò richiederebbe conoscere in anticipo il token (cronologia del browser / registri proxy / registri del server) che è un ostacolo, ma è fattibile in determinate circostanze.Caso molto specifico, ma ho pensato che valesse la pena menzionarlo.
#2
+9
stuartm9999
2018-08-03 13:20:29 UTC
view on stackexchange narkive permalink

"non è possibile che un browser fornisca automaticamente le credenziali di autenticazione anche se in qualche modo viene indotto con l'inganno a visitare l'endpoint API"

Fai solo attenzione alle reti private che utilizzano autenticazione Windows / Kerberos. In questo scenario il browser fornirà automaticamente le credenziali (kerberos o token NTLM) se configurato per farlo.

Quindi, credo che in questo caso sia richiesto CSRF.

Sì.https://www.owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery "Autorizza le richieste basate solo sulle credenziali che vengono inviate automaticamente come il cookie di sessione se attualmente connesso all'applicazione, o la funzionalità" Ricordami "se non connessol'applicazione, ** o un token Kerberos ** se parte di una Intranet che partecipa all'accesso integrato con Active Directory è a rischio. "
#3
+7
an0904
2019-04-23 00:15:17 UTC
view on stackexchange narkive permalink

La necessità o meno della protezione CSRF si basa su 2 fattori: -

La richiesta sta eseguendo un'azione di modifica dello stato (non è la stessa dell'API REST senza stato) - Stato cambiare le azioni è qualsiasi azione che cambierà lo stato dell'applicazione .. per esempio eliminare qualcosa, aggiungere qualcosa, aggiornare qualcosa. Si tratta di azioni mediante le quali l'applicazione cambierà lo stato supportato dell'utente. Tutte le richieste di post e alcune richieste Get rientreranno in questa categoria. Le API REST possono avere azioni di modifica dello stato.

L'autenticazione è fornita dal browser (non limitata ai cookie) - CSRF avviene perché le informazioni di autenticazione sono incluse nella richiesta del browser indipendentemente dal la richiesta è stata avviata dall'utente o da qualche altra scheda aperta. Pertanto, qualsiasi tipo di autenticazione in cui il browser possa includere automaticamente le informazioni necessita di protezione CSRF. Ciò include sia sessioni basate su cookie che autenticazione di base.

Per tutte le richieste che rientrano in 2 categorie superiori è necessaria la protezione CSRF.

#4
+5
Charlie Reitzel
2019-09-25 01:06:33 UTC
view on stackexchange narkive permalink

Una cosa che aggiungerei alle altre risposte è che la protezione CSRF è necessaria solo nel dominio e nel percorso del cookie in questione. Oppure, in altre parole:

Autorizzazione! = Autenticazione
Cookie == Autenticazione
Token == Autorizzazione

Ciò è rilevante per l'implementazione di accessi persistenti (il tuo 3 ° punto). Se apponi i tuoi cookie a login.example.com , che ospita la tua interfaccia utente di accesso e il tuo endpoint / authorize , puoi eseguire un flusso OAuth implicito ogni pochi minuti senza richiedere un nuovo login (es. nessuna finestra di dialogo per la password). Il client può andare avanti e inviare il token di accesso così acquisito a api.example.com senza CSRF, poiché nessun cookie verrà inviato a quell'host.

Quindi, puoi ancora evitare in modo sicuro di trattare con CSRF sulle API REST. Ma è meglio che il tuo server di login / autenticazione sia a prova di proiettile (e protetto da CSRF).

#5
+4
John Wu
2017-08-04 01:28:59 UTC
view on stackexchange narkive permalink

Gli endpoint dell'API Rest hanno una differenza molto importante dalle altre richieste: sono specificamente senza stato e non dovrebbero mai accettare / utilizzare i dati da un cookie o da una sessione.

Se è così che definisci "REST API", allora nessun CSRF è possibile. CSRF, chiamato anche "session riding" [ citazione], ovviamente non funzionerà se non ci sono sessioni da "ride".

Se non sei d'accordo con una parte della mia dichiarazione, sarei felice di ascoltarla.IMO, l'apolidia è un obiettivo centrale delle API REST.Le sessioni sicuramente rendono un'API stateful.Cookie ... tecnicamente suppongo che tu possa usare i cookie e non memorizzare lo stato lato server, a seconda di come li usi.
Beh, preferisco rispondere alla domanda che cavillare sulla terminologia.Ma la S in HATEOS e la S in REST stanno entrambe per stato.Finché lo stato del client non è mantenuto sul server, non penso che tu abbia "violato" lo spirito dell'approccio REST.
Sono assolutamente d'accordo con te.Non avevo voglia di cavillare sulla terminologia.Parte del problema è che non ero abbastanza chiaro nella mia domanda originale: stavo parlando specificamente dello stato del client, non dello stato dell'applicazione.
Sì Trasferimento statale, questo è il punto importante.Lo stato non è memorizzato sul lato server.Il client comunica al server il suo stato.E CSRF ha senso solo se l'API è accessibile tramite normali browser web.Alcuni metodi http come DELETE, PUT / PATCH non sono nemmeno supportati dai browser odierni, il che rende l'api accessibile solo ai client http stand-alone.
#6
+2
Raywell
2020-02-07 15:39:47 UTC
view on stackexchange narkive permalink

Risposta : se memorizzi il token nel localStorage e lo aggiungi alle tue richieste con JS, garantirà automaticamente la protezione CSRF (per la natura dell'attacco)

Addendum : se è più sicuro utilizzare i cookie solo http piuttosto che localStorage (fare in modo che sembri che questo modo di avere la protezione CSRF creerebbe un problema in caso di XSS): in realtà non lo è . Sarebbe solo un po 'più difficile per l'attaccante che ha il controllo di JS sul tuo sito tramite un XSS sfruttato. @ Bobince lo ha spiegato con parole migliori: L'impostazione di http impedisce solo il furto di una sessione utilizzando XSS?

XSS è una vulnerabilità a livello di applicazione, ma i suoi effetti possono essere mitigati limitando la potenza del token attraverso l'uso di attestazioni (limitati al minimo necessario)

Benvenuto.In quanto sito di domande e risposte, siamo diversi da un sito di discussione.Le risposte devono essere autonome come risposta alla domanda e non come commento su un'altra risposta.
Grazie @schroeder.Poster per la prima volta da molto tempo in agguato, inizialmente volevo commentare, ma ciò richiedeva una reputazione minima.Tuttavia quel commento ha portato alla mia risposta originale alla domanda OP nella mia ultima frase: "dovrei usare la protezione csrf" => No se il token è memorizzato e aggiunto all'intestazione da JS
Tutto quello che posso dire è: continua a contribuire al sito per ottenere abbastanza rep per sbloccare la possibilità di commentare.Hai fatto il primo passo per uscire dal "lurk".Continua così :)
Ti consiglio di rimuovere il commento dall'altra risposta e assicurarti che questa risposta affronti direttamente la domanda.
Posso, ma penso che sia abbastanza importante perché fa la differenza (ragionamento che porta alla risposta).Chiarirò la conclusione
Ho riformulato la risposta, spero che sembri meno una discussione (i contenuti sono praticamente gli stessi).Sto aspettando la mia reputazione per commentare la parte fuorviante nella risposta accettata. Nel frattempo mi sto godendo la mia immagine del profilo con la svastica generata automaticamente
#7
+1
Dean Valentine
2020-08-13 09:20:55 UTC
view on stackexchange narkive permalink

C'è un piccolo avvertimento specifico per le risposte esistenti che vorrei aggiungere. Sebbene Conor abbia ragione sul fatto che i cookie sono l'unica forma di dati di autenticazione memorizzati localmente inviati insieme a tutte le richieste, non sono l'unica forma di dati di autenticazione memorizzati localmente utilizzati dai siti web. Ciò significa che se un sito decide di mantenere i propri token JWT / Session in qualcosa come LocalStorage o SessionStorage, a volte questi possono ancora essere estratti automaticamente tramite javascript e quindi utilizzati senza l'interazione dell'utente. Ciò significa che a volte è ancora possibile eseguire attacchi CSRF "una volta rimossi" reindirizzando un utente a un URI di frontend corrispondente al dominio che quindi invia le credenziali. Questo può essere ottenuto in modo più diretto se hai riflesso XSS, ma ci sono casi in cui questo non è necessario e tali pagine + script esistono già.

In questi casi, il problema non è la mancanza di Token CSRF sull'API REST; è la mancanza di token sugli endpoint di qualunque frontend interagisca con esso.

Wow, è geniale!Così banale, se un JS potesse essere in qualche modo iniettato nel sito di destinazione, qualsiasi sessione potrebbe essere rubata.
@peterh-ReinstateMonica Carino, ma come ho detto nel post non è quello che intendevo.Non è raro che tu abbia un frontend seduto di fronte all'API rest con alcuni endpoint che eseguono già azioni mutative al caricamento, senza richiedere di iniettare codice in essi.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...