• sicurezza
  • oauth
  • PKCE

Un breve richiamo sulla sicurezza di OAuth

Quanto sei esperto nelle misure di protezione impiegate da OAuth? Il tuo sistema aderisce allo standard aperto di OAuth? Sei consapevole dei potenziali rischi che potrebbero sorgere durante l'implementazione del flusso di autenticazione dell'utente? Rivediamo brevemente quello che abbiamo appreso su OAuth.

Simeng
Simeng
Developer

Introduzione

Qualche giorno fa, è stato pubblicato un interessante articolo sulla vulnerabilità di OAuth. A-new-oauth-vulnerability-that-may-impact-hundreds-of-online-services dal laboratorio SALT. Questo specifico post evidenzia una vulnerabilità scoperta in Expo, un framework ampiamente utilizzato per l'implementazione di OAuth e altre funzionalità. Si tratta specificamente di una vulnerabilità nella libreria expo-auth-session, che è stata assegnata e correttamente risolta.

Se hai interesse per OAuth o stai lavorando su un prodotto correlato a CIAM come noi, ti consigliamo vivamente di leggere questo articolo. È molto stimolante e fornisce utili spunti. Queste relazioni di white-hat servono come promemoria di come anche la più semplice funzionalità può causare vulnerabilità. Quando si tratta di sicurezza informatica e autorizzazione, non si può mai essere troppo prudenti nel garantire la sicurezza e la privacy delle informazioni degli utenti. Se questo articolo cattura la tua attenzione, credo che sarai fortemente d'accordo con noi.

Mi ricorda il tempo in cui abbiamo iniziato. Abbiamo dedicato molto tempo all'apprendimento e alla ricerca dei dettagli dei protocolli OAuth e OIDC. Era doloroso e noioso, ma i benefici erano immensi. Sebbene forse non tutti i membri del nostro team siano esperti di OAuth, tutti sono impegnati a mettere continuamente impegno verso la sicurezza e la meticolosità. Con questi sforzi dedicati, il prodotto Logto si è evoluto in quello che è oggi.

Grazie a questa grande opportunità, vorremmo rinfrescare la nostra memoria su alcuni dei dettagli di sicurezza di OAuth qui.

Uno sguardo al flusso di autorizzazione del codice OAuth

OAuth 2.0 fornisce vari flussi di autorizzazione che si adattano a diversi tipi di client e requisiti. Questi includono il Implicit Flow, Client Credentials Flow, Resource Owner Password Credentials Flow, e Device Authorization Flow. Tuttavia, il flusso di codice di autorizzazione si distingue come il più sicuro e ampiamente utilizzato. A differenza di altri flussi, separa l'autenticazione dell'utente dall'applicazione del cliente e comporta lo scambio di un Codice di Autorizzazione per i token. Questo approccio fornisce un ulteriore livello di sicurezza, in quanto i token sensibili non vengono mai esposti al cliente. Inoltre, il flusso di Codice di Autorizzazione supporta la gestione dei token lato server, rendendolo adatto per applicazioni web che richiedono una sicurezza robusta e un controllo migliorato sull'accesso degli utenti.

Questo è un diagramma del Authorization Code Flow più semplice:

Diamo uno sguardo alle due richieste più cruciali effettuate nel flusso di concessione del codice di autorizzazione e ai frammenti apparentemente banali all'interno di esse, ma che svolgono un ruolo critico nella protezione contro le frodi.

L'endpoint di autorizzazione:

Il punto di scambio del token:

Credenziali del cliente

In OAuth, le Client Credentials si riferiscono alle credenziali utilizzate da un'applicazione cliente per autenticarsi e identificarsi presso il server di autorizzazione. Queste credenziali sono ottenute durante il processo di registrazione del cliente e vengono utilizzate per convalidare l'identità del cliente quando effettua richieste al server di autorizzazione. (Puoi trovare le tue credenziali client nella console Admin di Logto quando hai la tua applicazione registrata per la prima volta.)

Le credenziali del cliente sono tipicamente composte da due componenti:

  1. ID Client: Un identificatore unico assegnato all'applicazione cliente dal server di autorizzazione. È un valore pubblico che generalmente non viene considerato sensibile.
  2. Segreto del cliente: Un valore confidenziale e conservato in modo sicuro noto solo al cliente e al server di autorizzazione. Serve come forma di autenticazione per l'applicazione cliente ed è utilizzato per verificare l'identità del cliente quando effettua richieste al server di autorizzazione.

Come puoi vedere, la combinazione ID Client e Segreto del Cliente viene utilizzata durante la richiesta del token per autenticare il cliente e ottenere Token di Accesso.

Le credenziali del cliente svolgono un ruolo vitale nel garantire la sicurezza del flusso OAuth. Aiutano il server di autorizzazione a verificare l'autenticità delle applicazioni cliente e a controllare l'accesso alle risorse protette. È importante gestire in modo sicuro le credenziali del cliente e proteggerle da accessi non autorizzati. Logto categorizza le applicazioni del cliente in due diversi livelli di sicurezza:

  • Clienti confidenziali: Questi includono applicazioni web renderizzate sul server e applicazioni machine-to-machine (M2M). Nel caso di clienti confidenziali, tutte le credenziali relative all'autorizzazione, comprese le credenziali del cliente, sono conservate in modo sicuro dal lato server. Inoltre, tutte le richieste intermedie di scambio vengono crittografate per garantire la riservatezza dei dati. Il rischio di perdita delle credenziali del cliente per i clienti confidenziali è molto basso, rendendoli intrinsecamente più sicuri. Pertanto, i clienti confidenziali sono trattati con un livello di sicurezza più alto per impostazione predefinita. Nel flusso di scambio del token, presentare il Segreto del Cliente è un MUST.
  • Clienti pubblici: Questi includono applicazioni web di una sola pagina (SPA) e applicazioni native. Per i clienti pubblici, le credenziali del cliente sono tipicamente codificate in modo rigido dal lato cliente, ad esempio all'interno di un pacchetto JavaScript o di un pacchetto di app su una piattaforma nativa. Il rischio di perdita delle credenziali è superiore rispetto ai clienti confidenziali a causa dell'esposizione intrinseca delle credenziali del cliente nel codice lato cliente. Nel flusso di scambio del token, presentare il Segreto del Cliente è FACOLTATIVO. Logto non si fiderà di quelle credenziali da un cliente pubblico per impostazione predefinita.

Stato

Nel flusso OAuth, il parametro state è un valore generato casualmente che viene incluso nella richiesta di autorizzazione inviata dal cliente al server di autorizzazione. Il suo scopo è di mantenere lo stato o il contesto della richiesta del cliente durante tutto il processo di autorizzazione.

Il parametro state funge da misura di sicurezza per prevenire attacchi cross-site request forgery (CSRF). Quando il server di autorizzazione reindirizza l'utente all'applicazione cliente dopo l'autenticazione e l'autorizzazione, include lo stesso valore di stato nella risposta. L'applicazione cliente DEVE confrontare questo valore con il valore state originale che ha inviato nella richiesta di autorizzazione.

Verificando il parametro di stato, il cliente può garantire che la risposta ricevuta dal server di autorizzazione corrisponda alla richiesta iniziale che ha effettuato. Questo aiuta a prevenire attacchi in cui un attaccante cerca di ingannare il cliente nell'accettazione di una risposta destinata ad un altro utente o applicazione.

Prendiamo l'esempio di un attacco CSRF in un caso d'uso fittizio:

Attacco CSRF: Frode per legare account social - problema

Con un adeguato meccanismo di convalida dello stato, il cliente può rilevare l'attacco e impedire all'utente di essere reindirizzato al sito web dell'attaccante:

Attacco CSRF: Frode per legare l'account social - soluzione

PKCE

Come accennato in precedenza, i client pubblici come le applicazioni web SPA e le applicazioni native comportano un rischio maggiore di perdita delle credenziali di autenticazione, compreso il Codice di Autorizzazione emesso dal server di autorizzazione.

PKCE è l'acronimo di Proof Key for Code Exchange. È un'estensione di Authorization Code Flow di OAuth 2.0 che aumenta la sicurezza dei client pubblici.

PKCE è stato introdotto per mitigare il rischio che un attaccante intercetti il Codice di Autorizzazione e lo scambi per un Access Token senza che il client ne sia a conoscenza. Questo tipo di attacco, noto come attacco di intercettazione del Codice di Autorizzazione, è più diffuso in ambienti in cui l'applicazione cliente non può conservare in modo sicuro un segreto del cliente.

Per implementare PKCE, l'applicazione cliente genera un Verificatore di Codice casuale e ne deriva una Sfida di Codice utilizzando un specifico algoritmo di hashing (generalmente SHA-256). La Sfida di Codice è inclusa nella richiesta di autorizzazione iniziale inviata al server di autorizzazione.

Quando il server di autorizzazione emette il Codice di Autorizzazione, l'applicazione cliente include il Verificatore di Codice originale nella richiesta del token. Il server verifica che il Verificatore di Codice corrisponda alla Sfida di Codice memorizzata e solo allora emette l'Access Token.

Utilizzando PKCE, l'applicazione cliente garantisce che il solo Codice di Autorizzazione non è sufficiente per ottenere un Access Token. Questo meccanismo aggiunge un ulteriore livello di sicurezza al flusso di autorizzazione, specialmente per i client pubblici in cui la memorizzazione dei Segreti del Cliente è complicata.

Logto utilizza PKCE come l'UNICO flusso di autorizzazione per tutte le applicazioni di tipo cliente pubblico. Tuttavia, PKCE e può essere omesso per quei clienti confidenziali.

Redirect URI

Un Redirect URI(Uniform Resource Identifier) è un endpoint specifico o un URL che il server di autorizzazione reindirizza l'utente dopo il processo di autenticazione e autorizzazione in OAuth.

Durante il flusso OAuth, l'applicazione cliente include un Redirect URI come parte della richiesta di autorizzazione iniziale. Questo URI funge da URL di callback in cui l'utente verrà reindirizzato dopo aver autenticato con successo e concesso i permessi al cliente.

Una volta che l'utente ha completato il processo di autenticazione, il server di autorizzazione genera una risposta che include un Codice di Autorizzazione, e reindirizza l'utente torna all'URI di reindirizzamento specificato.

La convalida dell'URI di reindirizzamento è un passo essenziale nel garantire la sicurezza e l'integrità del flusso OAuth. Implica la convalida che l'URI di reindirizzamento utilizzato nella richiesta di autorizzazione e nei reindirizzamenti successivi sia valido e affidabile.

Torniamo indietro e diamo un'occhiata al rapporto di vulnerabilità di OAuth originale. (La seguente sezione è presa dal post originale)

Quando l'utente fa clic su "login con facebook" utilizzando l'APP Mobile in Expo Go, reindirizza l'utente al seguente link:

https://auth.expo.io/@moreisless3/me321/start?authUrl=https://www.facebook.com/v6.0/dialog/oauth?code_challenge=...&display=popup&auth_nonce=...&code_challenge_method=S256&redirect_uri=https://auth.expo.io/@moreisless3/me321&client_id=3287341734837076&response_type=code,token&state=gBpzi0quEg&scope=public_profile,email&returnUrl=exp://192.168.14.41:19000/--/expo-auth-session

Nella risposta, auth.expo.io imposta il seguente cookie: ru=exp://192.168.14.41:19000/--/expo-auth-session. Il valore RU verrà utilizzato successivamente come Return Url nel passaggio 5. Quindi mostra all'utente un messaggio di conferma, e se l'utente approva - viene reindirizzato al login di Facebook per continuare il flusso di autenticazione

Questa pagina legge il parametro di query "returnUrl" e imposta il cookie di conseguenza.

Proviamo a cambiare il returnUrl in hTTps://attacker.com (https non è permesso, quindi ho provato ad inserire lettere maiuscole e ha funzionato), che imposta il RU (Return Url) nel cookie a https://attacker.com.

Nel caso sopra, gettando via i parametri redirect_uri originali, Expo ha introdotto un nuovo parametro chiamato returnUrl senza una convalida appropriata. Questo errore di valutazione ha fornito un'opportunità per gli attaccanti per ottenere accesso al Codice di Autorizzazione restituito da Facebook. Per ulteriori dettagli, si prega di consultare il post originale.

La convalida del Redirect URI svolge diversi scopi importanti:

  1. Prevenire gli attacchi di phishing: Convalidando l'URI di reindirizzamento, il server di autorizzazione garantisce che l'utente venga reindirizzato a un endpoint di fiducia e autorizzato. Questo aiuta a prevenire che gli attaccanti reindirizzino gli utenti a posizioni dannose o non autorizzate.
  2. Proteggersi dai reindirizzamenti aperti: I reindirizzamenti aperti sono vulnerabilità che possono essere sfruttate per reindirizzare gli utenti a siti web dannosi. Convalidando l'URI di reindirizzamento, il server di autorizzazione può garantire che il reindirizzo rimanga entro i confini del dominio autorizzato o del gruppo di domini fidati.
  3. Garantire il corretto inoltro delle risposte di autorizzazione: Convalidando l'URI di reindirizzamento, si garantisce che il server di autorizzazione reindirizzi l'utente all'applicazione cliente prevista. Assicura così che la risposta, come un Codice di Autorizzazione o un Token di Accesso, venga consegnato alla destinazione corretta.

In Logto, la registrazione di redirect_uri è obbligatoria per tutti i tipi di applicazioni. Confrontiamo e abbiniamo il valore ricevuto con quelli registrati nel server Logto. Ciò include eventuali parametri di ricerca personalizzati. Se una richiesta di autorizzazione fallisce la validazione a causa di un valore redirect_uri mancante, non valido o corrispondente, verrà restituito un errore di URI di Redirezione non valido all'URI di reindirizzamento registrato in file.

A causa della loro natura intricata e sfumata, è comprensibile che questi dettagli vengano spesso trascurati. Alcuni sono solo una stringa casuale come state.

Tuttavia, è importante notare che queste misure di sicurezza aggiungono strati di protezione all'autorizzazione dell'utente, mitigando rischi come attacchi CSRF, intercettazione del Codice di Autorizzazione e reindirizzamenti non autorizzati.

Questi sono solo una piccola parte delle funzionalità di sicurezza complete offerte dal protocollo OAuth. OAuth fornisce un framework robusto per l'autenticazione e l'autorizzazione sicure. Offre anche endpoint flessibili e aperti per soddisfare vari requisiti nelle applicazioni di prodotti del mondo reale.

Come sviluppatori e fornitori di servizi, è imperativo continuare a dare la priorità alla sicurezza del flusso di autorizzazione degli utenti. Rimanere vigili, aderire alle migliori pratiche e mantenersi aggiornati sulle ultime novità nell'ecosistema OAuth sono essenziali per garantire l'integrità e la protezione delle identità degli utenti e dei dati sensibili. Ci impegneremo a mantenere i più alti standard di sicurezza nell'implementazione di OAuth e a tutelare la privacy e la fiducia dei nostri utenti.