Perché i token di accesso scadono?


209

Ho appena iniziato a lavorare con l'API di Google e OAuth2. Quando il client autorizza la mia app mi viene assegnato un "token di aggiornamento" e un "token di accesso" di breve durata. Ora ogni volta che scade il token di accesso, POSSO inviare il mio token di aggiornamento a Google e mi daranno un nuovo token di accesso.

La mia domanda è: qual è lo scopo del token di accesso in scadenza? Perché non può esserci un token di accesso di lunga durata anziché il token di aggiornamento?

Inoltre, il token di aggiornamento scade?

Consulta Utilizzo di OAuth 2.0 per accedere alle API di Google per ulteriori informazioni sul flusso di lavoro di Google OAuth2.

Risposte:


226

Questo è molto specifico per l'implementazione, ma l'idea generale è quella di consentire ai provider di emettere token di accesso a breve termine con token di aggiornamento a lungo termine. Perché?

  • Molti provider supportano token al portatore che sono molto deboli dal punto di vista della sicurezza. Rendendoli di breve durata e richiedendo un aggiornamento, limitano il tempo in cui un attaccante può abusare di un token rubato.
  • La distribuzione su larga scala non vuole eseguire una ricerca nel database ad ogni chiamata API, quindi emette un token di accesso autocodificato che può essere verificato mediante decodifica. Tuttavia, ciò significa anche che non è possibile revocare questi token, quindi vengono emessi per un breve periodo e devono essere aggiornati.
  • Il token di aggiornamento richiede l'autenticazione client che lo rende più forte. A differenza dei token di accesso di cui sopra, di solito è implementato con una ricerca nel database.

4
Due domande: 1) Nel caso delle app mobili, il requisito per l'autenticazione client lo rende più forte? Perché client_secret fa parte del codice sorgente dell'applicazione, quindi non è affatto segreto. Supponendo che anche il token di accesso sia condiviso solo tramite TLS (e il primo punto elenco non si applica) esiste una sicurezza aggiuntiva? 2) Supponendo che tutto ciò valga nel nostro scenario (solo TLS, nessun token non codificabile autocodificante), è corretto emettere token di accesso che non scadono?
Thilo,

4
Che cos'è un token bearer e cosa ha a che fare con i token di aggiornamento e accesso?
codice alleato

7
@Thilo Penso che l'idea sia che i token di accesso non debbano essere revocabili. Come sottolinea Eran, ciò consente al servizio richiesto di decidere se soddisfare una richiesta <em> senza dover cercare il token di accesso in alcuni database </em>. AFAICT, questo è il vero vantaggio della separazione dei token di aggiornamento e dei token di accesso.
codice alleato

5
Come può un token di accesso (portatore?) Di breve durata? Se invio una richiesta con un token di portatore scaduto, il token di aggiornamento restituirà un nuovo token di portatore. Allo stesso modo, se rubo il token di qualcuno dai suoi cookie e falsifico il mio cookie con quel token, lo invio al server, si aggiornerà e me ne invierà uno nuovo. Cosa può fermarlo? Non dire indirizzo IP o MAC, perché è irragionevole.
Suamere,

3
@Suamere, questo è già stato spiegato. I token di connessione sono convalidati da un processo di crittografia che non tocca il database di autenticazione, rendendoli molto più efficienti per l'accesso frequente alle risorse. I token di aggiornamento vengono convalidati in un processo che prevede il controllo del database per assicurarsi che sia ancora valido. Ora pensa a come funziona Gmail. Se qualcuno accede al tuo account da una posizione geografica imprevista, puoi ricevere un avviso. Puoi vedere tutte le posizioni che potrebbero avere token di aggiornamento attualmente validi. È possibile disconnettersi da tutte le posizioni, invalidando tutti gli altri token di aggiornamento.
Bon

33

Un paio di scenari potrebbero aiutare a illustrare lo scopo dell'accesso e dei token di aggiornamento e i compromessi ingegneristici nella progettazione di un sistema oauth2 (o di qualsiasi altra autorizzazione):

Scenario di app Web

Nello scenario dell'app Web sono disponibili un paio di opzioni:

  1. se si dispone della propria gestione della sessione, archiviare sia access_token che refresh_token sull'ID sessione nello stato sessione sul servizio stato sessione. Quando una pagina viene richiesta dall'utente che richiede di accedere alla risorsa, utilizzare access_token e se access_token è scaduto, utilizzare refresh_token per ottenere quello nuovo.

Immaginiamo che qualcuno riesca a dirottare la tua sessione. L'unica cosa che è possibile è richiedere le tue pagine.

  1. se non si dispone della gestione della sessione, inserire access_token in un cookie e utilizzarlo come sessione. Quindi, ogni volta che l'utente richiede pagine dal tuo server web invia access_token. Il server delle app potrebbe aggiornare access_token se necessario.

Confronto tra 1 e 2:

In 1, access_token e refresh_token viaggiano solo attraverso il filo lungo la strada tra il server di autorizzazione (google nel tuo caso) e il tuo server app. Questo sarebbe fatto su un canale sicuro. Un hacker potrebbe dirottare la sessione ma potrebbe interagire solo con la tua app web. In 2, l'hacker potrebbe rimuovere access_token e formare le proprie richieste alle risorse a cui l'utente ha concesso l'accesso. Anche se l'hacker ottiene un access_token avranno solo una breve finestra in cui possono accedere alle risorse.

In ogni caso, refresh_token e clientid / secret sono noti solo al server, rendendo impossibile dal browser web ottenere l'accesso a lungo termine.

Immaginiamo di implementare oauth2 e impostare un timeout lungo sul token di accesso:

In 1) Non c'è molta differenza qui tra un token di accesso breve e lungo poiché è nascosto nel server delle app. In 2) qualcuno potrebbe ottenere il token di accesso nel browser e quindi utilizzarlo per accedere direttamente alle risorse dell'utente per un lungo periodo.

Scenario mobile

Sul cellulare, ci sono un paio di scenari che conosco:

  1. Archivia clientid / secret sul dispositivo e fai orchestrare il dispositivo ottenendo l'accesso alle risorse dell'utente.

  2. Utilizzare un server app back-end per contenere il clientid / secret e fare in modo che l'orchestrazione. Utilizzare access_token come una specie di chiave di sessione e passarlo tra il client e il server delle app.

Confronto tra 1 e 2

In 1) Una volta che hai clientid / segreto sul dispositivo, non sono più segreti. Chiunque può decompilare e quindi iniziare a comportarsi come se fossi tu, con il permesso dell'utente ovviamente. Anche access_token e refresh_token sono in memoria e sono accessibili su un dispositivo compromesso, il che significa che qualcuno potrebbe agire come app senza che l'utente fornisca le proprie credenziali. In questo scenario la lunghezza di access_token non fa differenza per l'hackability poiché refresh_token si trova nello stesso posto di access_token. In 2) il clientid / secret né il token di aggiornamento sono compromessi. Qui la durata della scadenza di access_token determina per quanto tempo un hacker potrebbe accedere alle risorse degli utenti, se dovessero ottenerlo.

Lunghezze di scadenza

Qui dipende da cosa stai proteggendo con il tuo sistema di autenticazione su quanto dovrebbe durare la tua scadenza di access_token. Se è qualcosa di particolarmente prezioso per l'utente, dovrebbe essere breve. Qualcosa di meno prezioso, può essere più lungo.

Alcune persone come Google non scadono il refresh_token. Ad alcuni piace stackflow. La decisione sulla scadenza è un compromesso tra facilità d'uso e sicurezza. La lunghezza del token di aggiornamento è correlata alla lunghezza di ritorno dell'utente, ovvero imposta l'aggiornamento sulla frequenza con cui l'utente ritorna alla tua app. Se il token di aggiornamento non scade, l'unico modo per essere revocato è con una revoca esplicita. Normalmente, un accesso non viene revocato.

Spero che un post piuttosto lungo sia utile.


su MOBILE SCENARIO è importante se memorizzi l'ID client nel tuo server. quindi chiunque altro può semplicemente inviare una richiesta al tuo server e accedere alle risorse degli utenti tramite il tuo server, quindi è lo stesso
Amir Bar

vero, ma poi hanno accesso solo alle strutture fornite, piuttosto che al pieno accesso al token sottostante. Cioè possono impersonare la tua app. Spesso i token possono disporre di autorizzazioni estese, mentre è necessario solo un sottoinsieme. Tenere premuto il token nel backend fornisce ulteriori restrizioni, se necessario.
Ed Sykes,

11

Oltre alle altre risposte:

Una volta ottenuti, i token di accesso vengono in genere inviati insieme a ogni richiesta dai client ai server di risorse protetti. Ciò comporta il rischio di furto e riproduzione di token di accesso (presupponendo ovviamente che i token di accesso siano di tipo "Portatore" (come definito nella RFC6750 iniziale).

Esempi di tali rischi, nella vita reale:

  • I server di risorse in genere sono server di applicazioni distribuite e in genere presentano livelli di sicurezza inferiori rispetto ai server di autorizzazione (configurazione SSL / TLS inferiore, protezione avanzata, ecc.). D'altro canto, i server di autorizzazione sono generalmente considerati infrastrutture di sicurezza critiche e sono soggetti a un rafforzamento più grave.

  • I token di accesso possono essere visualizzati in tracce, registri, ecc. HTTP raccolti legittimamente a scopo diagnostico sui server delle risorse o sui client. Tali tracce possono essere scambiate su luoghi pubblici o semi-pubblici (bug traccianti, service desk, ecc.).

  • Le applicazioni di back-end RS possono essere esternalizzate a terze parti più o meno affidabili.

Il token di aggiornamento, invece, viene in genere trasmesso solo due volte sui cavi e sempre tra il client e il server di autorizzazione: una volta ottenuto dal client e una volta utilizzato dal client durante l'aggiornamento ("scadendo" effettivamente il precedente aggiornamento gettone). Questa è un'opportunità drasticamente limitata per l'intercettazione e la riproduzione.

Ultimo pensiero, i token di aggiornamento offrono pochissima protezione, se presente, contro i client compromessi.


Hai in qualche modo toccato questo aspetto, ma vorrei sottolineare che la più ampia superficie di attacco per ottenere (o al contrario divulgare involontariamente token) si trova nei registri delle applicazioni o nei servizi di risorse aggiunti in modo nefasto (non un attacco MITM oggi). Quasi ovunque in un back-end API comune ha accesso al token di accesso utilizzato (se ha accesso all'oggetto HttpRequest ecc.). Solo DUE percorsi di codice nel sistema hanno accesso al token di aggiornamento, quello che lo genera in primo luogo e quello che lo scambia con un nuovo token di accesso. Questa è una differenza significativa nella superficie di attacco.
Tom Dibble,

9

È essenzialmente una misura di sicurezza. Se la tua app è compromessa, l'utente malintenzionato avrà accesso al token di accesso di breve durata e non potrà generarne uno nuovo.

Anche i token di aggiornamento scadono, ma dovrebbero vivere molto più a lungo del token di accesso.


45
Ma l'attaccante non avrebbe anche accesso al token di aggiornamento? e puoi utilizzarlo per creare un nuovo token di accesso?
levi,

10
@levi, l'hacker non può utilizzare il token di aggiornamento per creare un nuovo token di accesso perché l'ID client e il segreto client sono necessari insieme al token di aggiornamento per generare il nuovo token di accesso.
Spike

9
@Spike Vero, ma l'app non ha anche l'ID client e il segreto integrati?
Andy,

9
Quindi fornisce una certa protezione dallo sniffing dei pacchetti, purché l'intercettazione rilevi solo le normali richieste di dati (Chuck ottiene solo il token di accesso)? Sembra un po 'debole; il cappello nero deve solo aspettare un po 'fino a quando l'utente richiede un nuovo token di accesso e quindi riceverà l'ID client, il segreto e il token di aggiornamento.

3
Questo potrebbe essere il mio ritardo qui, ma se questo viene inviato tramite SSL non si aggiunge a un altro possibile livello di sicurezza. Suppongo che suppongo che tutti sappiano cos'è SSL.
Damon Drake,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.