OAuth 2.0 è un protocollo che dà ad un client API un accesso limitato ai dati degli utenti su un server web. Ad esempio, viene utilizzato dalle API di GitHub, Google e Facebook. Esso si basa su scenari di autenticazione chiamati flussi, che permettono al proprietario della risorsa (l’utente) di condividere il contenuto protetto dal server della risorsa senza condividere le proprie credenziali. A tale scopo, un server OAuth 2.0 emette dei token di accesso che le applicazioni client possono utilizzare per accedere alle risorse protette per conto del proprietario della risorsa.
La specifica OAuth 2.0 definisce quattro ruoli:
Il flusso di OAuth 2.0 è cosi definito:
In questo articolo andremo ad approfondire alcuni degli attacchi principali al flusso tramite Authorization Code di OAuth 2.0 e alcune delle possibili mitigazioni.
Nota bene: le remediation effettuate di seguito sono state sviluppate solo come esempio e non devono essere seguite alla lettera o utilizzate in ambiente di produzione. Per risolvere possibili vulnerabilità consiglio di basarsi su RCF6819
Il seguente esempio è stato preso da Vulnerable-OAuth-2.0-Applications e modificato in base alle esigenze.
Il sito web di terze parti Photoprint consente agli utenti di stampare le immagini ospitate sul sito Gallery. L’applicazione Photoprint utilizza il Codice di Autorizzazione Grant.
L’interazione tra _Gallery _e _Photoprint _è la seguente:
Ricapitolando:
Come da specifiche, dopo aver completato la sua interazione con il Resource Owner, il server di autorizzazione redirige l’utente verso il client. Il server di autorizzazione reindirizza poi all’endpoint precedentemente stabilito con il server di autorizzazione durante il processo di registrazione del client o quando si effettua la richiesta di autorizzazione. Il redirect_uri è probabilmente uno dei parametri più vulnerabili del flusso di OAuth 2.0. Alcuni casi possono essere:
Il parametro code contiene il codice di autorizzazione ricevuto dall’Authorization Server per il Resource Owner. Quest’ultimo lo presenta poi al Client, in modo che possa utilizzarlo per ottenere l’accesso. Le vulnerabilità più comuni possono essere in merito a:
Il parametro State è stato introdotto per miticare attacchi di tipo Cross Site Request Forgery. Esso è consigliato e non obbligatorio nelle specifiche, anche se dovrebbe essere sempre utilizzato.
Il suo funzionamento è il seguente:
Il client_secret è un valore univoco per ogni resource server e permette di validare il code per gli access tokens.
Esso deve essere sempre mantenuto nascosto e non dev’essere visibile ad un normale utente. La sua divulgazione potrebbe permettere la violazione completa delle risorse del Resource Provider.
Se l’authorization server non verifica che l’url di reindirizzamento appartiene al client, è suscettibile a due tipi di attacchi
Un attaccante potrebbe utilizzare l’endpoint di autorizzazione dell’utente finale e il reindirizzamento del parametro redirect_url per abusare dell’authorization server. Modificando il valore dell’url in un sito malevolo, un aggressore può lanciare con successo una truffa di phishing e rubare le credenziali dell’utente. Poiché il nome del server nel link modificato è identico al sito originale, i tentativi di phishing hanno un aspetto più affidabile.
Un attaccante potrebbe utilizzare la fiducia di un utente nell’authorization server per lanciare un attacco di tipo phishing.
L’applicativo _Gallery _non valida il parametro redirect_url, rendendolo di fatto vulnerabile ad attacchi di questo tipo.
Una volta cliccato il link, il sito Gallery chiede, come da flusso normale, di accede alla galleria delle foto.
L’utente ignaro viene poi redirezionato verso un finto sito dove vengono richieste le credenziali a causa di un errore generico.
Una volta inserite, l’attaccante ha a disposizione le stesse.
Per ovviare a questa situazione, bisogna legare l’authorization code all’ID cliente e all’URI di reindirizzamento e, se necessario, creare una whitelist di domini che verranno utilizzati per il reindirizzamento.
Non appena un utente accede con successo al server di autenticazione, il server rinvia all’applicazione con un codice di autorizzazione. Successivamente questo codice di autorizzazione viene utilizzato per ottenere il token di accesso nel backend.
Un aggressore potrebbe rubare l’access_token per ottenere il codice di autorizzazione e accedere al server di risorse.
Per ovviare a questa situazione, bisogna legare l’authorization code all’ID cliente e all’URI di reindirizzamento e, se necessario, creare una whitelist di domini che verranno utilizzati per il reindirizzamento.
Un client malintenzionato potrebbe fingere di essere un client valido e ottenere un’autorizzazione all’accesso al resource server. Un attaccante potrebbe quindi avere accesso ai dati privati degli utenti.
L’authorization server dovrebbe vincolare ogni codice di autorizzazione all’id del rispettivo client che ha avviato il processo di autorizzazione dell’utente finale. Questa misura è una contromisura contro:
Un attaccante può tentare di indovinare i valori di “codice” di autorizzazione validi e inviare il valore del codice indovinato per ottenere un authorization token valido. Quando si creano segreti non destinati all’uso da parte di utenti umani, il server di autorizzazione dovrebbe includere un livello ragionevole di entropia al fine di mitigare il rischio di indovinare il token.
Il valore del token dovrebbe essere >=128 bit di lunghezza e costruito a partire da una sequenza numerica casuale o pseudo-casuale generata dal server di autorizzazione. La maggior parte dei framework OAuth 2.0 ormai lo implementano correttamente.
Ovviamente il token non viene generato in maniera cosi semplice, ma come precisato dev’essere lungo almeno 128 bit.
Cross-site request forgery è una vulnerabilità che permette ad un aggressore di indurre gli utenti a compiere azioni che non intendono compiere. Essa permette all’aggressore di aggirare in parte la same origin polocy che è progettata per evitare che siti web diversi interferiscano tra loro.
In un attacco CSRF riuscito, l’aggressore induce l’utente vittima a compiere un’azione involontaria. Ad esempio, può trattarsi di cambiare l’indirizzo e-mail sul proprio conto, di cambiare la password o di effettuare un trasferimento di fondi. A seconda della natura dell’azione, l’aggressore potrebbe essere in grado di ottenere il pieno controllo sul conto dell’utente. Se l’utente compromesso ha un ruolo privilegiato all’interno dell’applicazione, l’aggressore potrebbe essere in grado di assumere il pieno controllo di tutti i dati e le funzionalità dell’applicazione.
Nell’esempio di seguito, un attaccante ha creato una richiesta nascosta dietro un semplice bottone, dove, dopo aver sottratto i dati bancari della vittima, ha inviato alla stessa un sito di phishing dove chiede di cliccare un bottone per stampare le foto
Prima di redirezionare l’utente, aggiungere il parametro state e validarlo durante la navigazione, in modo che nessuno possa replicare le richieste in maniera malintenzionata e inconsapevole per l’utente.
Come abbiamo visto possono esserci, in aggiunta alle classiche vulnerabilità applicative, come SQL Injection, Cross Site Scripting, etc., anche una serie di problematiche in merito al semplice flusso di OAuth 2.0.
Nel RFC6819, denominata, OAuth 2.0 Threat Model and Security Considerations, sono inserite la maggior parte delle vulnerabilità che una errata implementazione del flusso può portare.
Oltre a quello, nel 2017 IETF (Internet Engineering Task Force) ha pubblicato una bozza denominata ‘OAuth 2.0 Security Best Current Practice’ nella quale vengono elencati i possibili attacchi a OAuth 2.0 e le mitigazioni agli stessi, in modo che chiunque potesse essere aggiornato e consapevole dei rischi associati ad errori di programmazione.