Svenska
  • säkerhet
  • oauth
  • PKCE

En kort sammanfattning av OAuth-säkerhet

Hur väl insatt är du i de skyddsåtgärder som används av OAuth? Följer ditt system den öppna standarden för OAuth? Är du medveten om de potentiella risker som kan uppstå under implementeringen av användarautentiseringsflödet? Låt oss kortfattat återkalla vad vi har lärt oss om OAuth.

Simeng
Simeng
Developer

Introduktion

För några dagar sedan publicerades en intressant artikel om en OAuth-sårbarhet. En-ny-oauth-sårbarhet-som-kan-påverka-hundratals-online-tjänster av SALT-labbet. Detta specifika inlägg belyser en sårbarhet som upptäcktes i Expo, ett mycket använt ramverk för implementering av OAuth och andra funktioner. Det behandlar specifikt en sårbarhet i expo-auth-session-biblioteket, som redan har tilldelats och åtgärdats ordentligt.

Om du är intresserad av OAuth eller arbetar på en CIAM-relaterad produkt som vi, rekommenderar vi starkt att du läser denna artikel. Den är ganska inspirerande och ger hjälpsamma insikter. Dessa vita hatt-rapporter fungerar som en påminnelse om hur även den enklaste funktionen kan orsaka sårbarheter. När det kommer till cybersäkerhet och auktorisering kan vi aldrig vara för försiktiga för att säkerställa säkerheten och integriteten för användarinformation. Om den här artikeln fångar ditt intresse tror jag att du kommer att hålla med oss starkt.

Det påminner mig om när vi först började. Vi ägnade mycket tid åt att lära oss och forska i detaljerna i OAuth och OIDC-protokollen. Det var smärtsamt och tråkigt, men fördelarna var enorma. Även om kanske inte varje individ i vårt team är en OAuth-expert, är alla engagerade i att lägga ner kontinuerlig ansträngning för säkerhet och noggrannhet. Med dessa hängivna ansträngningar har Logto-produkten utvecklats till vad den är idag.

Tack vare denna stora möjlighet vill vi fräscha upp vårt minne om några av säkerhetsdetaljerna i OAuth här.

En glimt av OAuth Authorization Code Flow

OAuth 2.0 erbjuder olika auktoriseringsflöden som tillgodoser olika kundtyper och krav. Dessa inkluderar Implicit Flow, Client Credentials Flow, Resource Owner Password Credentials Flow och Device Authorization Flow. Men Authorization Code Flow utmärker sig som det mest säkra och allmänt använda. Till skillnad från andra flöden separerar det användarautentisering från klientapplikationen och involverar utbyte av en Authorization Code mot token. Detta tillvägagångssätt ger ett extra säkerhetslager, eftersom de känsliga token aldrig exponeras för klienten. Dessutom stöder Authorization Code Flow serverbaserad tokenhantering, vilket gör det lämpligt för webbaserade applikationer som kräver robust säkerhet och förbättrad kontroll över användaråtkomst.

Här är ett enkelt Authorization Code Flow-diagram:

Låt oss ta en titt på de två viktigaste förfrågningarna i Authorization Code Grant-flödet och de till synes triviala fragmenten inom dem men som spelar en avgörande roll för att skydda mot bedrägerier.

Auktoriseringsendpoint:

Tokenutbyte-endpoint:

Klientuppgifter

I OAuth refererar Klientuppgifter till de autentiseringsuppgifter som används av en klientapplikation för att autentisera och identifiera sig själv för auktoriseringsservern. Dessa uppgifter erhålls under klientregistreringsprocessen och används för att validera klientens identitet när förfrågningar görs till auktoriseringsservern. (Du kan hitta dina klientuppgifter i Logtos administrationskonsol när du först registrerat din applikation.)

Klientuppgifter består vanligtvis av två komponenter:

  1. Klient-ID: Ett unikt identifierare tilldelat klientapplikationen av auktoriseringsservern. Det är ett offentligt värde som vanligtvis inte anses vara känsligt.
  2. Klienthemlighet: Ett konfidentiellt och säkert lagrat värde känt endast av klienten och auktoriseringsservern. Det fungerar som en form av autentisering för klientapplikationen och används för att verifiera klientens identitet när förfrågningar görs till auktoriseringsservern.

Som du kanske märker, används kombinationen av Klient-ID och Klienthemlighet under tokenförfrågan för att autentisera klienten och erhålla Access Token.

Klientuppgifterna spelar en avgörande roll för att säkerställa säkerheten i OAuth-flödet. De hjälper auktoriseringsservern att verifiera äktheten hos klientapplikationer och kontrollera åtkomst till skyddade resurser. Det är viktigt att hantera klientuppgifter på ett säkert sätt och skydda dem från obehörig åtkomst. Logto kategoriserar klientapplikationerna i två olika säkerhetsnivåer:

  • Konfidentiella klienter: Dessa inkluderar server-renderade webbaserade applikationer och maskin-till-maskin (M2M) applikationer. För konfidentiella klienter lagras alla autentiseringsrelaterade uppgifter, inklusive klientuppgifter, säkert på serversidan. Dessutom är alla mellanlagringstransaktioner krypterade för att säkerställa datakonfidentialitet. Risken för läckage av klientuppgifter för konfidentiella klienter är mycket låg, vilket gör dem av natur mer säkra. Därför behandlas konfidentiella klienter med en högre säkerhetsnivå som standard. I tokenutbytesflödet är det ett KRAV att presentera Klienthemlighet.
  • Offentliga klienter: Dessa inkluderar enkel-side webbaserade applikationer (SPA) och inhemska applikationer. För offentliga klienter är klientuppgifterna vanligtvis hårdkodade på klientsidan, som inom ett Java Script-paket eller ett applikationspaket på en inhemsk plattform. Risken för läcka av referensuppgifter är högre jämfört med konfidentiella klienter på grund av att klientuppgifter exponeras i klientens kod. I tokenutbytesflödet är det FRIVILLIGT att presentera Klienthemlighet. Logto litar inte på dessa referenser från en offentlig klient som standard.

State

I OAuth-flödet är state-parametern ett slumpmässigt genererat värde som inkluderas i auktoriseringsförfrågan som skickas av klienten till auktoriseringsservern. Dess syfte är att bibehålla tillståndet eller sammanhanget för klientens förfrågan genom hela auktoriseringsprocessen.

state-parametern fungerar som en säkerhetsåtgärd för att förhindra cross-site request forgery (CSRF) attacker. När auktoriseringsservern omdirigerar användaren tillbaka till klientapplikationen efter autentisering och auktorisering, inkluderar den samma tillståndsvärde i svaret. Klientapplikationen MÅSTE jämföra detta värde med det ursprungliga state-värdet den skickade i auktoriseringsförfrågan.

Genom att verifiera state-parametern kan klienten försäkra sig om att svaret från auktoriseringsservern motsvarar den ursprungliga förfrågan den gjorde. Detta hjälper till att förhindra attacker där en angripare försöker lura klienten att acceptera ett svar avsett för en annan användare eller applikation.

Ta följande CSRF-attackexempel i ett fiktivt användningsfall:

CSRF-attack: Bedrägeri för att binda socialt konto - problem

Med en korrekt state-valideringsmekanism kan klienten upptäcka attacken och förhindra att användaren omdirigeras till angriparens webbplats:

CSRF-attack: Bedrägeri för att binda socialt konto - lösning

PKCE

Som nämnts tidigare, offentliga klienter som SPA webbaserade appar och inhemska applikationer bär en högre risk för läckage av autentiseringsuppgifter, inklusive Authorization Code utfärdad av auktoriseringsservern.

PKCE står för Proof Key for Code Exchange. Det är en utökning av OAuth 2.0 Authorization Code Flow som förbättrar säkerheten för offentliga klienter.

PKCE infördes för att minska risken för att en angripare avlyssnar Authorization Code och byter ut den mot en Access Token utan klientens kännedom. Denna typ av attack, känd som en Authorization Code-avlyssningsattack, är mer utbredd i miljöer där klientapplikationen inte kan lagra en klienthemlighet säkert.

För att implementera PKCE, genererar klientapplikationen en slumpmässig Code Verifier och härleder en Code Challenge från den med en specifik hash-algoritm (vanligtvis SHA-256). Code Challenge inkluderas i den initiala auktoriseringsförfrågan som skickas till auktoriseringsservern.

När auktoriseringsservern utfärdar Authorization Code, inkluderar klientapplikationen original Code Verifier i tokenförfrågan. Servern verifierar att Code Verifier matchar den lagrade Code Challenge och utfärdar då först Access Token.

Genom att använda PKCE, säkerställer klientapplikationen att Authorization Code ensam inte är tillräcklig för att erhålla en Access Token. Denna mekanism lägger till ett extra säkerhetslager till auktoriseringsflödet, särskilt för offentliga klienter där lagring av Klienthemligheter är utmanande.

Logto använder PKCE som DET ENDA auktoriseringsflödet för alla offentliga klienttyped applikationer. Dock kan PKCE och utelämnas för de konfidentiella klienterna.

Redirect URI

En Redirect URI(Uniform Resource Identifier) är en specifik endpoint eller URL som auktoriseringsservern omdirigerar användaren tillbaka till efter autentiserings- och auktoriseringsprocessen i OAuth.

Under OAuth-flödet inkluderar klientapplikationen en Redirect URI som en del av den initiala auktoriseringsförfrågan. Denna URI fungerar som callback-URL där användaren kommer att omdirigeras efter att ha autentiserats framgångsrikt och beviljat behörigheter till klienten.

När användaren slutför autentiseringsprocessen genererar auktoriseringsservern ett svar som inkluderar en Authorization Code, och omdirigerar användaren tillbaka till den specificerade Redirect URI.

Validering av Redirect URI är ett viktigt steg för att säkerställa säkerheten och integriteten hos OAuth-flödet. Det innebär att verifiera att den Redirect URI som används i auktoriseringsförfrågan och efterföljande omdirigeringar är giltiga och pålitliga.

Låt oss återgå och ta en titt på den ursprungliga OAuth-sårbarhetsrapporten. (Följande avsnitt är refererat från det ursprungliga inlägget)

När användaren klickar på “logga in med facebook” via mobilappen i Expo Go, omdirigeras den till användaren till följande länk:

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

I svaret, auth.expo.io sätter följande cookie: ru=exp://192.168.14.41:19000/--/expo-auth-session. Värdet RU kommer att användas senare som ett Retur-URL i steg 5. Det visar sedan användaren ett bekräftelsemeddelande, och om användaren godkänner - omdirigeras den till Facebook-inloggningen för att fortsätta autentiseringsflödet

Denna sida läser frågeparametern “returnUrl” och ställer in cookien därefter.

Låt oss ändra returnUrl till hTTps://attacker.com (https är inte tillåtet, så jag försökte infoga versaler och det fungerade), vilket ställer in RU (Retur-URL) i cookien till https://attacker.com.

I fallet ovan, bortse från original redirect_uri-parametrar, introducerade Expo en ny parameter kallad returnUrl utan korrekt validering. Detta förbiseende gav en möjlighet för angripare att få tillgång till Authorization Code återvände av Facebook. För mer detaljer, vänligen se den ursprungliga inlägget.

Valideringen av Redirect URI tjänar flera viktiga syften:

  1. Förhindrar nätfiskeattacker: Genom att validera Redirect URI säkerställer auktoriseringsservern att användaren omdirigeras tillbaka till en pålitlig och auktoriserad endpoint. Detta hjälper till att förhindra att angripare omdirigerar användare till skadliga eller obehöriga platser.
  2. Skyddar mot öppna omdirigeringar: Öppna omdirigeringar är sårbarheter som kan utnyttjas för att omdirigera användare till skadliga webbplatser. Genom att validera Redirect URI, kan auktorisationsservern säkerställa att omdirigeringen stannar inom gränserna för den auktoriserade domänen eller ett utsett domänpaket.
  3. Säkerställer korrekt routning av auktoriseringssvar: Validering av Redirect URI hjälper till att garantera att auktoriseringsservern omdirigerar användaren tillbaka till den avsedda klientapplikationen. Det säkerställer att svaret, såsom en Authorization Code eller Access Token, levereras till rätt destination.

I Logto är registrering av redirect_uri obligatorisk för alla typer av applikationer. Vi jämför och matchar det mottagna värdet mot de registrerade i Logto-servern. Det inkluderar eventuella anpassade sökparametrar. Om en auktoriseringsförfrågan misslyckas med valideringen på grund av ett saknat, ogiltigt eller missmatchande redirect_uri-värde, kommer ett ogiltigt Redirect URI-fel att returneras till den registrerade redirect_uri i register.

Sammanfattning

På grund av deras komplicerade och nyanserade karaktär är det förståeligt att dessa detaljer ofta förbises. Vissa är bara en slumpmässig sträng som state.

Dock är det viktigt att notera att dessa säkerhetsåtgärder lägger till skyddslager till användarauktorisation, vilket minimerar risker såsom CSRF-attacker, Authorization Code-avlyssning, och obehöriga omdirigeringar.

Dessa är bara en liten del av de omfattande säkerhetsfunktioner som erbjuds av OAuth-protokollet. OAuth tillhandahåller ett robust ramverk för säker autentisering och auktorisering. Det erbjuder också flexibla och öppna endpoints för att möta olika krav i verkliga produktapplikationer.

Som utvecklare och tjänsteleverantörer är det viktigt att kontinuerligt prioritera säkerheten för användarauktorisationsflödet. Att hålla sig vaksam, följa bästa praxis och hålla sig uppdaterad med den senaste utvecklingen inom OAuth-ekosystemet är avgörande för att säkerställa integriteten och skyddet av användaridentiteter och känslig data. Vi kommer att förbli engagerade i att upprätthålla de högsta säkerhetsstandarderna i implementeringen av OAuth och skydda våra användares integritet och förtroende.