CORS e CSRF Prevenzione per un'API basata su REST

4

Attualmente sto cercando di capire come prevenire CSRF.

La mia prima soluzione era usare un token che è suggerito ovunque. Ovviamente risolverebbe questo problema:

<img src="http://api.example.com/me/delete">

Maquellochenonriescoacapireèquello.

GEThttp://api.example.com/me/delete

Effettivamentefalliràperchéuntokenvalidononèarrivatoconquellarichiesta,macosaimpedisceaunutentemalintenzionatodifarequantosopraeinvecedifaresoloilseguente

GEThttp://api.example.com/me/token/generate//parsetheresponseGEThttp://api.example.com/me/delete?token=...

Iltokenvalidoèstatopassatolungolarichiesta,ilmioutenteèoracancellato...

LamiaAPIRESTconsenteaqualsiasirichiestadiarrivare.

header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]);

Il motivo per cui ho "bisogno" è che, non sto solo usando l'API REST sul dominio stesso attraverso moduli e JavaScript. Ma sto facendo richieste usando cURL in C ++.

Se i token in questo caso non sono una soluzione "sicura", allora quale sarebbe / potrebbe essere una soluzione più sicura / migliore?

Inoltre cosa fa Spotify, mentre entrambi hanno la loro "Web API" e il software musicale stesso?

Inoltre, so che questo è molto interessante, ma è possibile consentire qualsiasi accesso alla mia API ma avere un'autenticazione per origine?

In tal modo che se il collegamento è "connesso" all'API, ciò non significa che link è (o successivo quando si richiede l'uso di cURL).

So che questo è inverosimile, poiché la "soluzione" sarebbe controllare l'intestazione di origine, ma ciò può essere falsificato.

    
posta Vallentin 08.06.2015 - 15:52
fonte

3 risposte

7

La Stessa politica di origine normalmente impedirebbe che lo scenario si verificasse:

GET http://api.example.com/me/token/generate
// parse the response

La risposta non può essere analizzata attraverso un dominio di terze parti che effettua richieste al tuo dominio. Normalmente il browser lo blocca a causa del SOP.

Dico normalmente perché hai anche aggiunto la seguente intestazione di risposta per rilassare le stesse regole di origine:

header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]);

Sotto il seguente malinteso:

The reason I "need" that is that, I'm not only using the REST API on the domain itself through forms and JavaScript. But I'm doing requests using cURL in C++.

Questa intestazione non ha alcuna rilevanza su cURL. L'intestazione viene analizzata solo dai browser, implementando il SOP. Non fa nulla per impedire che arrivino richieste dirette per un client web.

Soluzione

Sul tuo dominio api.example.com , consenti al front-end di effettuare richieste tramite il browser dell'utente:

Access-Control-Allow-Origin: example.com

Sul tuo sito example.com , invia la seguente intestazione con tutte le richieste API AJAX:

X-Requested-With: XMLHttpRequest

Vedi questa risposta per informazioni su questo . In breve, questa intestazione non può essere inviata al dominio incrociato senza che il CORS sia abilitato.

Verifica sul backend dell'API che questa intestazione sia presente quando viene ricevuta una richiesta. Se non lo è, allora è un attacco CSRF.

Sulle tue richieste lato server usando cURL, aggiungi semplicemente l'intestazione manualmente. per es.

X-Requested-With: cURL

Mentre stai verificando che sia presente, queste richieste avranno successo.

Infine, aggiungi qualche autenticazione usando i cookie. Gli utenti del tuo sito Web che hanno effettuato l'accesso devono disporre di un ticket di autenticazione che può essere inviato in un cookie, e dovresti averne uno per le tue richieste di backend cURL da utilizzare. Ciò assicurerà che nessuno possa utilizzare la tua API senza permesso. Potresti voler limitare le azioni che gli utenti Web possono eseguire utilizzando i livelli di autorizzazione perché altrimenti potrebbero tentare di eseguire maliziosamente una funzione che solo lo strumento server CURL dovrebbe eseguire.

    
risposta data 27.09.2015 - 12:48
fonte
1

Spero di aver capito la tua domanda.

Come per la prima parte, Normalmente, poiché l'autore dell'attacco sarà su origine diversa del tuo server, il browser non consentirà a di leggere la risposta impedendogli così di "analizzare la risposta" e di inviare il token in una richiesta successiva. Ma hai esplicitamente permesso tutte le origini che rendono questa protezione inutile.

Inoltre, il token generato dovrebbe ovviamente richiedere l'autenticazione di qualche tipo, in cui il token dell'utente A non sarà valido per l'utente B, quindi anche se invierà manualmente il token, non sarà valido.

Seconda parte, Se disponevi di un qualche tipo di meccanismo di token correttamente implementato, indipendentemente da dove proveniva la richiesta, il token avrebbe impedito l'attività dannosa.

Per quanto riguarda la terza parte, se ho capito correttamente la tua domanda: Per quanto riguarda il funzionamento da un browser, CORS non consente di impostare l'origine utilizzando javascript o qualsiasi codice lato client . Quindi, nel caso di un attacco CSRF che richiede un certo valore per Origin, l' utente malintenzionato non può falsificare quel valore usando Javascript.

Spero che ti aiuti.

    
risposta data 08.06.2015 - 18:19
fonte
1

Considerando lo scenario della domanda originale, penso che il token OAuth / JWT sia l'approccio raccomandato. Per tali scenari, si desidera consentire ad altre origini di avere accesso alle proprie API, ma si accettano solo quelle richieste che sono autorizzate. È qui che un token JWT fornisce questo livello di sicurezza in quanto le attestazioni vengono aggiunte al token e puoi aggiungere i filtri di autorizzazione in base a tali attestazioni.

Per coloro che desiderano solo consentire le stesse richieste di origine, nessuna autenticazione dell'utente e impedire CSRF, un token anti-contraffazione con un filtro di convalida può fare il trucco. Un caso tipico potrebbe essere un modulo di contatto. Per ulteriori informazioni su questo, dai un'occhiata a questo esempio con un'app angularjs:

link

spero che aiuti.

    
risposta data 10.03.2016 - 18:55
fonte