Perché ci fidiamo delle informazioni di sessione sul filo ma non di un token di accesso OAuth?

8

Ho dedicato molto tempo alla creazione di un'API che deve essere accessibile da un'applicazione JavaScript a pagina singola e su come renderla il più sicura possibile.

Molto di quello che sto leggendo su standard come OAuth suggeriscono che non vuoi mai che il token di accesso che hai emesso sia reso disponibile direttamente al client, ed è per questo che cose come la Sovvenzione implicita sono spesso criticate.

Recentemente ho letto questo articolo: link

... che offriva un interessante suggerimento di inoltrare richieste all'API attraverso un componente lato server sottile, in modo che l'app a pagina singola potesse autenticarsi con il proxy, ottenere un cookie di sessione crittografato e quindi effettuare richieste al proxy server che collega il token di accesso dell'utente alle richieste prima di inoltrarle all'API effettiva.

Quello che mi chiedo è come questo sia più sicuro di un semplice token di accesso al client? Se l'utente malintenzionato sarebbe stato in grado di ottenere il token di accesso, sicuramente potrebbe ottenere il cookie che memorizza le informazioni sulla sessione che è buono quanto il token di accesso per effettuare richieste all'API?

Perché consideriamo sicuri i cookie crittografati con i dettagli della sessione, ma la fiducia nel client con il token di accesso effettivo è considerata non sicura?

La vera differenza è che un'API senza accesso diretto al client è considerata un'API privata e sicura e qualsiasi API che deve essere accessibile dal lato client in qualsiasi modo (anche attraverso un proxy) deve essere trattata come un'API pubblica o aperta, e devi solo accettare il trade dal rischio che qualcuno sia potenzialmente in grado di falsificare le richieste se sono in grado di mettere le mani sul cookie di sessione o sul token di accesso?

Qual è in realtà il modo più sicuro per un'applicazione a singola pagina per dimostrare la sua identità a un'API?

    
posta adam 09.12.2014 - 15:27
fonte

4 risposte

5

If the attacker would've been able to get the access token, surely they can get the cookie storing the session information

Un attacco XSS non può accedere al cookie se lo si specifica con HttpOnly. Deve essere stata una svista, avrebbe dovuto dirlo davvero. Oh, e sicuro (solo HTTPS). Quindi questo cookie non può essere rubato tramite XSS o MitM'd / sniffato.

Why is it that we consider encrypted cookies with session details in them safe,

Quindi mettendo i token in un cookie contrassegnato come HttpOnly, sono al sicuro da XSS. Riconoscendoli, hai impedito loro di essere trapelati, intenzionalmente o meno, ad esempio da parte dell'utente che ispezionava i suoi cookie.

but trusting the client with the actual access token is considered insecure?

Questo problema non è in realtà il client ma piuttosto un utente malintenzionato XSS, che potrebbe rubare il token di accesso e quindi impersonare l'utente.

Ma ora che stiamo usando i cookie, la sua ultima affermazione, fatta quasi come un ripensamento, è importante:

To protect an attacker just stealing the cookie you can use CSRF protection measures.

Per attenuare CSRF, è possibile applicare sul server che il client fornisce un'intestazione X-Requested-With (o altra personalizzata). Ciò impedirà ai siti dannosi o ai siti compromessi da XSS di chiamare le tue API perché le restrizioni tra domini del browser non consentiranno loro di aggiungere intestazioni personalizzate e quindi di rifiutarle.

What is actually the most secure way for a single page application to prove it's identity to an API?

Mi sono guardato intorno e penso che questo approccio, usando un lato server proxy, sia. Troverete varianti di esso altrove su google, ad esempio qui e qui , ma l'approccio di Alex Bilbie di crittografare access_token ha un vantaggio su questi due che non c'è mai una finestra (anche di breve durata) dove access_token è vulnerabile a XSS.

    
risposta data 16.03.2015 - 20:44
fonte
2

Il problema è che i token di accesso non sono legati al client. Quindi non c'è modo di sapere se un token di accesso è stato rilasciato per il tuo client o per un altro client.

Fondamentalmente, dal punto di vista di OAuth 2.0, chiunque possieda il token di accesso è TU.

Ho scritto una risposta grande che spiega come questo è un problema. Ecco l'attacco che puoi montare:

Let's say your REST service required an access token from facebook. All an attacker need to do is to host a service, for example stackoverflow, and require an access token from facebook. When you give the facebook access token to stackoverflow, stackoverflow (our attacker) can now impersonate you with your REST service.

Tutto ciò perché i token di accesso non sono associati a un client specifico.

Potrebbe sembrare strano che OAuth permetta qualcosa del genere ma è vero. OAuth presume semplicemente che il rischio sia accettabile perché era pensato solo per l'autorizzazione e non per l'autenticazione. E questo è il prossimo grande problema. La maggior parte delle persone non conosce la differenza tra autorizzazione e autenticazione e utilizza in modo errato OAuth a destra e a sinistra.

Parte della confusione deriva dal fatto che il flusso Codice di autorizzazione fornisce anche l'autenticazione come un effetto collaterale ... Ti suggerisco di leggere la seguente sezione nella specifica OAuth:

What is actually the most secure way for a single page application to prove it's identity to an API?

Se vuoi l'autenticazione, usa OpenID. OpenID era pensato per l'autenticazione. OAuth è solo l'autorizzazione.

OpenID è costruito su OAuth e aggiunge tutti i pezzi mancanti necessari per fornire l'autenticazione. Uno di questi è che, contrariamente a OAuth, OpenID associa il token di accesso al client in modo che l'attacco sopra menzionato non funzioni più se si utilizza OpenID.

    
risposta data 06.01.2016 - 16:04
fonte
1

Penso che quello che sta cercando di dire è che non dovresti tenere tutte le chiavi nello stesso posto. La compartimentalizzazione del processo è ciò che svolge il ruolo chiave nel meccanismo di autenticazione che suggerisce.

Una cosa che dovresti tenere anche nota è trarre beneficio dalla stessa politica di origine . L'uso di SOP impedirà agli aggressori di manipolare i dati da un dominio diverso da quello a cui l'accesso ha accesso (a meno che non sfrutti il browser). E non utilizzare WebSockets per manipolare informazioni sensibili, non sono soggette a questa politica.

Parlando dello standard corrente (se questo è ciò che intendi per "il modo più sicuro") per farlo, lo lascerò agli sviluppatori qui ...

    
risposta data 09.12.2014 - 16:24
fonte
1

Why is it that we consider encrypted cookies with session details in them safe, but trusting the client with the actual access token is considered insecure?

Un altro elemento chiave dell'articolo di Alex Bilbie è che non è possibile eseguire la crittografia sul client (in javascript) perché non è possibile mantenere la chiave di decrittografia sicura, il che significa che chiunque può ottenere la chiave e decrittografare la roba crittografata.

Facendo il lato server di crittografia, la chiave segreta non viene mai esposta al client, che ha semplicemente un token 'opaco' per offrire fino a servizi.

A parte questa aggiunta, sono completamente d'accordo con Steve Kehlet.

    
risposta data 06.01.2016 - 14:56
fonte

Leggi altre domande sui tag