Een korte samenvatting van OAuth-beveiliging
Hoe goed ben je op de hoogte van de beveiligingsmaatregelen die door OAuth worden gebruikt? Voldoet jouw systeem aan de open standaard van OAuth? Ben je je bewust van de mogelijke risico's die kunnen optreden tijdens de implementatie van de gebruikersauthenticatieflow? Laten we kort samenvatten wat we hebben geleerd over OAuth.
Introductie
Een paar dagen geleden bereikte ons een interessant artikel over een OAuth-kwetsbaarheid. Een-nieuwe-oauth-kwetsbaarheid-die-honderden-online-diensten-kan-treffen door het SALT-lab. Deze specifieke post benadrukt een kwetsbaarheid ontdekt in Expo, een veelgebruikt framework voor het implementeren van OAuth en andere functionaliteiten. Het richt zich specifiek op een kwetsbaarheid in de expo-auth-session-bibliotheek, die al is toegewezen en correct opgelost.
Als je geïnteresseerd bent in OAuth of werkt aan een CIAM-gerelateerd product zoals wij, raden we aan dit artikel te lezen. Het is erg inspirerend en biedt nuttige inzichten. Deze white-hat-rapporten dienen als een herinnering dat zelfs de eenvoudigste functie kwetsbaarheden kan veroorzaken. Als het gaat om cyberbeveiliging en autorisatie, kunnen we nooit te voorzichtig zijn om de veiligheid en privacy van gebruikersinformatie te waarborgen. Als dit artikel je aandacht trekt, geloof ik dat je het sterk met ons eens zult zijn.
Het herinnert me aan de tijd toen we net begonnen. We besteedden veel tijd aan het leren en onderzoeken van de details van de OAuth- en OIDC-protocollen. Het was pijnlijk en vervelend, maar de voordelen waren enorm. Hoewel misschien niet elk individu in ons team een OAuth-expert is, is iedereen toegewijd aan het voortdurend leveren van inspanningen voor veiligheid en nauwkeurigheid. Dankzij die toegewijde inspanningen is het Logto-product geëvolueerd tot wat het vandaag is.
Dankzij deze geweldige kans willen we hier enkele van de beveiligingsdetails van OAuth opnieuw onder de aandacht brengen.
Een kijkje in de OAuth Authorization Code Flow
OAuth 2.0 biedt verschillende autorisatiestromen die tegemoetkomen aan verschillende cliënttypen en vereisten. Deze omvatten de Implicit Flow, Client Credentials Flow, Resource Owner Password Credentials Flow, en Device Authorization Flow. De Authorization Code Flow valt echter op als de meest veilige en wijdverspreide. In tegenstelling tot andere stromen, scheidt het gebruikersauthenticatie van de clientapplicatie en omvat het een uitwisseling van een Authorization Code voor tokens. Deze benadering biedt een extra beveiligingslaag, aangezien de gevoelige tokens nooit aan de client worden blootgesteld. Bovendien ondersteunt de Authorization Code Flow server-side tokenbeheer, waardoor het geschikt is voor webapplicaties die robuuste beveiliging en verbeterde controle over gebruikersrechten vereisen.
Hier is een eenvoudig diagram van de Authorization Code Flow:
Laten we eens kijken naar de twee meest cruciale verzoeken die worden gedaan in de Authorization Code Grant-flow en de schijnbaar triviale fragmenten daarin, maar die een cruciale rol spelen bij het beschermen tegen fraude.
Het autorisatie-eindpunt:
Het tokenuitwisseling-eindpunt:
Client Credentials
In OAuth verwijzen Client Credentials naar de referenties die door een clientapplicatie worden gebruikt om zichzelf te authentiseren en te identificeren bij de autorisatieserver. Deze credentials worden verkregen tijdens het clientregistratieproces en worden gebruikt om de identiteit van de client te valideren wanneer er verzoeken worden gedaan aan de autorisatieserver. (Je kunt je clientcredential vinden in het Logto Admin-console wanneer je je applicatie voor het eerst hebt geregistreerd.)
Clientcredentials bestaan meestal uit twee componenten:
- Client ID: Een unieke identificator die door de autorisatieserver aan de clientapplicatie is toegewezen. Het is een openbare waarde die over het algemeen niet als gevoelig wordt beschouwd.
- Client Secret: Een vertrouwelijke en veilig opgeslagen waarde die alleen bekend is bij de client en de autorisatieserver. Het dient als een vorm van authenticatie voor de clientapplicatie en wordt gebruikt om de identiteit van de client te verifiëren wanneer er verzoeken worden gedaan aan de autorisatieserver.
Zoals je misschien ziet, wordt de combinatie van Client ID en Client Secret gebruikt tijdens het tokenverzoek om de client te authenticeren en Access Tokens te verkrijgen.
De clientcredentials spelen een cruciale rol bij het waarborgen van de beveiliging van de OAuth-stroom. Ze helpen de autorisatieserver de authenticiteit van clientapplicaties te verifiëren en toegang tot beschermde bronnen te controleren. Het is belangrijk om clientcredentials veilig te beheren en ze te beschermen tegen ongeautoriseerde toegang. Logto categoriseert de clientapplicaties op twee verschillende beveiligingsniveaus:
- Vertrouwelijke clients: Hiertoe behoren server-gerenderde webapplicaties en machine-to-machine (M2M) applicaties. In het geval van vertrouwelijke clients worden alle aan autorisatie gerelateerde credentials, inclusief clientcredentials, veilig opgeslagen aan de serverzijde. Bovendien worden alle tussenliggende uitwisselingsverzoeken versleuteld om de vertrouwelijkheid van gegevens te waarborgen. Het risico op het lekken van clientcredentials voor vertrouwelijke clients is zeer laag, waardoor ze inherent veiliger zijn. Daarom worden vertrouwelijke clients standaard met een hoger beveiligingsniveau behandeld. In de tokenuitwisseling-stroom is het presenteren van de Client Secret een MUST.
- Openbare clients: Hiertoe behoren single-page webapplicaties (SPA) en native applicaties. Voor openbare clients zijn de clientcredentials meestal hard gecodeerd aan de clientzijde, zoals binnen een JavaScript-pakket of een app-pakket in een native platform. Het risico op credential-lekkage is hoger in vergelijking met vertrouwelijke clients vanwege de inherente blootstelling van clientcredentials in de client-side code. In de tokenuitwisseling-stroom is het presenteren van de Client Secret OPTIONEEL. Logto vertrouwt die credentials niet standaard van een openbare client.
State
In de OAuth-stroom is de state
-parameter een willekeurig gegenereerde waarde die is opgenomen in het autorisatieverzoek dat door de client naar de autorisatieserver wordt verzonden. Het doel is om de staat of context van het verzoek van de client gedurende het autorisatieproces te behouden.
De state
-parameter fungeert als een beveiligingsmaatregel om cross-site request forgery (CSRF) aanvallen te voorkomen. Wanneer de autorisatieserver de gebruiker terugstuurt naar de clientapplicatie na authenticatie en autorisatie, bevat deze dezelfde state-waarde in de respons. De clientapplicatie MOET
deze waarde vergelijken met de oorspronkelijke state
-waarde die in het autorisatieverzoek werd verzonden.
Door de state-parameter te verifiëren, kan de client ervoor zorgen dat de respons die van de autorisatieserver is ontvangen, overeenkomt met het oorspronkelijke verzoek dat hij heeft gedaan. Dit helpt aanvallen te voorkomen waarbij een aanvaller probeert de client te misleiden om een respons te accepteren die bedoeld is voor een andere gebruiker of applicatie.
Neem het volgende CSRF-aanvalvoorbeeld in een fictief gebruiksgeval:
CSRF-aanval: Fraude om sociaal account te binden - probleem
Met een goede state-validatiemechanisme kan de client de aanval detecteren en voorkomen dat de gebruiker wordt omgeleid naar de website van de aanvaller:
CSRF-aanval: Fraude om sociaal account te binden - oplossing
PKCE
Zoals eerder vermeld, dragen openbare clients zoals SPA-webapps en native applicaties een hoger risico op auth credential-lekkage, inclusief de Authorization Code die door de autorisatieserver is uitgegeven.
PKCE staat voor Proof Key for Code Exchange. Het is een uitbreiding van de OAuth 2.0 Authorization Code Flow die de veiligheid van openbare clients verbetert.
PKCE werd geïntroduceerd om het risico te beperken dat een aanvaller de Authorization Code onderschept en deze zonder medeweten van de client inwisselt voor een Access Token. Dit type aanval, bekend als een Authorization Code interception attack, is meer voorkomend in omgevingen waar de clientapplicatie niet op een veilige manier een client secret kan opslaan.
Om PKCE te implementeren, genereert de clientapplicatie een willekeurige Code Verifier en leidt hieruit een Code Challenge af met behulp van een specifieke hashing-algoritme (meestal SHA-256). De Code Challenge is opgenomen in het initiële autorisatieverzoek dat naar de autorisatieserver wordt verzonden.
Wanneer de autorisatieserver de Authorization Code uitgeeft, bevat de clientapplicatie de oorspronkelijke Code Verifier in het tokenaanvraag. De server controleert of de Code Verifier overeenkomt met de opgeslagen Code Challenge en geeft alleen dan de Access Token uit.
Door PKCE te gebruiken, zorgt de clientapplicatie ervoor dat alleen de Authorization Code niet voldoende is om een Access Token te verkrijgen. Dit mechanisme voegt een extra beveiligingslaag toe aan de autorisatiestroom, vooral voor openbare clients waar het opslaan van Client Secrets een uitdaging is.
Logto gebruikt PKCE als de ENIGE autorisatiestroom voor alle public client-gebaseerde applicaties. PKCE kan echter worden weggelaten voor die vertrouwelijke clients.
Redirect URI
Een Redirect URI (Uniform Resource Identifier) is een specifieke eindpunt of URL waar de autorisatieserver de gebruiker naartoe terugleidt na het authenticatie- en autorisatieproces in OAuth.
Tijdens de OAuth-stroom omvat de clientapplicatie een Redirect URI als onderdeel van het initiële autorisatieverzoek. Deze URI fungeert als de callback-URL waar de gebruiker naartoe wordt teruggeleid na succesvolle authenticatie en toestemmingsverlening aan de client.
Zodra de gebruiker het authenticatieproces voltooit, genereert de autorisatieserver een respons met daarin een Authorization Code en leidt de gebruiker terug naar de gespecificeerde Redirect URI.
De validatie van Redirect URI is een essentiële stap in het waarborgen van de beveiliging en integriteit van de OAuth-stroom. Het omvat het controleren of de Redirect URI die in het autorisatieverzoek en daaropvolgende omleidingen wordt gebruikt, geldig en vertrouwd is.
Laten we teruggaan en een kijkje nemen naar het origineel OAuth-kwetsbaarheidsrapport. (Het volgende gedeelte is afkomstig uit het originele bericht)
Wanneer de gebruiker “login met Facebook” gebruikt in de Mobile APP in Expo Go, wordt de gebruiker doorgestuurd naar de volgende 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
In de reactie stelt auth.expo.io de volgende cookie in: ru=exp://192.168.14.41:19000/--/expo-auth-session. De waarde RU zal later worden gebruikt als een Return Url in stap 5. Het toont de gebruiker vervolgens een bevestigingsbericht, en als de gebruiker goedkeurt - wordt deze doorgestuurd naar de Facebook-login om verder te gaan met de authenticatiestroom
…
Deze pagina leest de queryparameter “returnUrl” en stelt de cookie dienovereenkomstig in.
Laten we de returnUrl veranderen in
hTTps://attacker.com
(https is niet toegestaan, dus ik probeerde hoofdletters in te voeren en het werkte), wat de RU (Return Url) in de cookie instelt ophttps://attacker.com
.…
In het bovenstaande geval negeert Expo de originele redirect_uri
-parameters en introduceert het een nieuwe parameter genaamd returnUrl zonder correcte validatie. Deze omissie bood aanvallers een kans om toegang te krijgen tot de Authorization Code die door Facebook werd geretourneerd. Voor meer details, zie het originele bericht.
Redirect URI-validatie dient verschillende belangrijke doelen:
- Voorkomen van phishing-aanvallen: Door de Redirect URI te valideren, zorgt de autorisatieserver ervoor dat de gebruiker wordt teruggeleid naar een vertrouwd en geautoriseerd eindpunt. Dit helpt te voorkomen dat aanvallers gebruikers naar kwaadaardige of ongeautoriseerde locaties omleiden.
- Bescherming tegen open omleidingen: Open omleidingen zijn kwetsbaarheden die kunnen worden uitgebuit om gebruikers naar kwaadaardige websites om te leiden. Door de Redirect URI te valideren, kan de autorisatieserver ervoor zorgen dat de omleiding binnen de grenzen van het geautoriseerde domein of de set van vertrouwde domeinen blijft.
- Zorgen voor correcte routering van autorisatiereacties: Validatie van de Redirect URI helpt ervoor te zorgen dat de autorisatieserver de gebruiker terugleidt naar de beoogde clientapplicatie. Zo wordt gewaarborgd dat de respons, zoals een Authorization Code of Access Token, naar de juiste bestemming wordt bezorgd.
In Logto is het registreren van redirect_uri
verplicht voor alle soorten applicaties. We vergelijken en matchen de ontvangen waarde met de geregistreerde waarden in de Logto-server. Dit omvat eventuele aangepaste zoekparameters. Als een autorisatieverzoek de validatie niet slaagt vanwege een ontbrekende, ongeldige of niet-overeenkomende redirect_uri
-waarde, wordt een ongeldige Redirect URI-fout geretourneerd naar de geregistreerde redirect_uri
in het bestand.
Samenvatting
Vanwege hun ingewikkelde en subtiele aard is het begrijpelijk dat deze details vaak over het hoofd worden gezien. Sommige zijn slechts een willekeurige string-achtige state
.
Het is echter belangrijk op te merken dat deze beveiligingsmaatregelen lagen van bescherming toevoegen aan gebruikersautorisatie, en risico's zoals CSRF-aanvallen, onderschepping van Authorization Codes en ongeautoriseerde omleidingen beperken.
Dit zijn slechts kleine stukjes van de uitgebreide beveiligingsfuncties die door het OAuth-protocol worden aangeboden. OAuth biedt een robuust framework voor veilige authenticatie en autorisatie. Het biedt ook flexibele en open eindpunten om aan verschillende vereisten in real-world producttoepassingen te voldoen.
Als ontwikkelaars en serviceproviders is het van essentieel belang om voortdurend prioriteit te geven aan de veiligheid van de gebruikersautorisatiestroom. Waakzaam blijven, het naleven van best practices, en op de hoogte blijven van de laatste ontwikkelingen in het OAuth-ecosysteem zijn essentieel om de integriteit en bescherming van gebruikersidentiteiten en gevoelige gegevens te waarborgen. We blijven ons inzetten voor het waarborgen van de hoogste normen van beveiliging in de implementatie van OAuth en het beschermen van de privacy en het vertrouwen van onze gebruikers.