Slide 1

Slide 1 text

OpenID Connect & OAuth 2.0 Security Best Practices Dominick Baier @leastprivilege

Slide 2

Slide 2 text

2 @leastprivilege Me • Independent Consultant – Specializing on Application Security Architectures & Security Protocols – Working with Software Development Teams (ISVs and in-house) • Co-Creator of IdentityServer & IdentityModel OSS Project – Certified OpenID Connect & OAuth 2.0 Engine for ASP.NET Core – https://identityserver.io • Co-Creator of PolicyServer – Authorization for modern Applications – https://policyserver.io email [email protected] blog https://leastprivilege.com twitter @leastprivilege slides https://speakerdeck.com/leastprivilege

Slide 3

Slide 3 text

3 @leastprivilege High Security OAuth FAPI https://fapi.openid.net

Slide 4

Slide 4 text

4 @leastprivilege Agenda • OAuth security best current practices & OAuth 2.1 – common attacks, countermeasures & recommendations • Advanced OAuth – tokens, scopes, resources and audience restrictions – rich authorization requests (RAR) – JWT secured authorization requests & request objects (JAR) – pushed authorization requests (PAR) – strong client authentication – proof-of-possession access tokens – delegation, impersonation and token exchange – "OAuth 3.0" outlook https://identityserver.io/training/advanced-oauth.html

Slide 5

Slide 5 text

5 @leastprivilege Some Context… 2005 SAML 2.0p WS-Federation WS-Trust 2007 2012 2014 2015 2017 Soon OAuth 2.0 Token Exchange OAuth 2.0 Mutual TLS OAuth 2.0 Resource Indicators JSON Web Token BCP OAuth 1.0 OAuth 2.0 Bearer Tokens OpenID Connect Core OpenID Connect Discovery OAuth 2.0 Assertion Framework OAuth 2.0 Dynamic Client Registration OAuth 2.0 Token Introspection JSON Web Token (JWT) OAuth 2.0 JSON Web Token (JWT) Profile OAuth 2.0 PKCE JAR, RAR, PAR JWT Access Token Profile OAuth 2.0 Security Topics BCP OAuth 2.0 for Browser-based Applications BCP OAuth 2.0 Threat Model & Security Considerations OAuth 2.0 for Native Apps BCP 2019/20 Future OAuth 2.1 "OAuth 3.0"

Slide 6

Slide 6 text

6 @leastprivilege Relevant Documents OAuth 2.0 Security Best Current Practice https://tools.ietf.org/html/draft-ietf-oauth- security-topics/ OAuth 2.0 Threat Model & Security Considerations https://tools.ietf.org/html/rfc6819 JSON Web Token Best Current Practices https://tools.ietf.org/html/rfc8725 OAuth 2.0 for native Applications https://tools.ietf.org/html/rfc8252 OAuth 2.0 for Browser-Based Applications https://tools.ietf.org/wg/oauth/draft-ietf-oauth-browser-based-apps/ JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens https://tools.ietf.org/wg/oauth/draft-ietf-oauth- access-token-jwt/

Slide 7

Slide 7 text

7 @leastprivilege The Big Picture Browser Native App Server App "Thing" Web App Web API Web API Web API Security Token Service

Slide 8

Slide 8 text

Simplified Client Resource Owner Resource Server Authorization Server 1 2

Slide 9

Slide 9 text

Attack Model (1) can read/write (unprotected) network traffic Client Resource Owner Resource Server Authorization Server 1 2 • no TLS • TLS compromise • other network infrastructure issues (e.g. DNS)

Slide 10

Slide 10 text

Attack Model (2) compromise of an endpoint Client Resource Owner Resource Server Authorization Server 1 2 • Client, AS or RS

Slide 11

Slide 11 text

Attack Model (3) additional endpoints Client Resource Owner Resource Server Authorization Server 1 2 • rogue client or RS registered with legit AS • trick legit client to trust rogue AS • trick user in using rogue client or RS • manipulation of network messages

Slide 12

Slide 12 text

Attack Model (4) Client Resource Owner Resource Server Authorization Server 1 2 can read, but not modify, the contents of the authorization request or response • open redirector vulnerabilities • client or AS • redirect interception on mobile devices • leakage • browser history • proxies • log files

Slide 13

Slide 13 text

13 @leastprivilege

Slide 14

Slide 14 text

14 @leastprivilege Implicit Flow Request GET /authorize ?client_id=app1 &redirect_uri=https://app.com/cb.html &response_type=token &state=j1y…a23 &scope=api1 api2

Slide 15

Slide 15 text

15 @leastprivilege Implicit Flow Response GET /callback.html #token=32x…133 &expires_in=3600 &token_type=Bearer &state=j1y…a23

Slide 16

Slide 16 text

16 @leastprivilege No more Implicit Flow • Implicit flow was a workaround in 2012 to overcome cross-origin AJAX limitations – solved now with CORS • Error prone – tokens are transmitted via URLs and can leak easily • log files • browser history • referrer headers • implementation errors • proxies – no solution for token injection attacks (without adding OpenID Connect)

Slide 17

Slide 17 text

17 @leastprivilege No more Password Grant • Exposes user's credentials to client – increased attack surface – credentials can leak in more places than just the authorization server – users are trained to type in credentials in multiple places • more prone to phishing attacks • Incompatible with modern authentication flows – FIDO – 2FA – federation

Slide 18

Slide 18 text

18 @leastprivilege Original Flows Application Type Flow Machine to Machine Client Credentials Flow Server-side Web Application OAuth Code Flow OpenID Connect Hybrid Flow Password Grant Native Desktop/Mobile Applications Implicit Flow OAuth Code Flow OpenID Connect Hybrid Flow Password Grant SPAs Implicit Flow Password Grant Code Flow

Slide 19

Slide 19 text

19 @leastprivilege Grand Unification Application Type Flow Machine to Machine Client Credentials Flow Interactive Application Code Flow + PKCE

Slide 20

Slide 20 text

20 @leastprivilege Machine to Machine APIs Authorization Server Scopes: api1, api2 api3… client_id/client_secret, scope=api1 api2 access token access token

Slide 21

Slide 21 text

21 @leastprivilege Client Authentication • Shared secrets are not recommended – can easily leak (configuration management, network traces, proxies…) – should have high entropy (e.g. GUIDs, RNGs) – should be stored non-reversible on authorization server • Asymmetric keys – no need to store any secret on authorization server – secret does not get transmitted over a network – provides key material for sender constraining – signed JWTs and/or Mutual TLS

Slide 22

Slide 22 text

22 @leastprivilege Bearer Tokens • No binding to client – attacker could use leaked token to call APIs – invoice.api can call customer.api (or vice versa) { "typ": "JWT", "alg": "RS256" "kid": "1" } { "iss": "https://my_issuer", "exp": "1340819380", "aud": [ "invoice.api", "customer.api" ] "client_id": "client1", } Header Payload JWT

Slide 23

Slide 23 text

23 @leastprivilege Interactive Applications • Browser redirect-based GET /authorize ?client_id=app1 &redirect_uri=https://app.com/cb GET /cb?code=xyz client id/secret/code access token 3 1 2

Slide 24

Slide 24 text

24 @leastprivilege Redirect URI Validation Attacks • Problematic – https://*.somesite.com/cb • e.g. sub-domain takeover – https://somesite.com/* • find a page with an open redirector • find a page where attacker can inject content GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=9ad67f13 &redirect_uri=https://somesite.com/some_endoint

Slide 25

Slide 25 text

25 @leastprivilege Credential Leakage via Referrer Headers • Might happen on client or authorization server GET /some_endpoint?code=xyz GET https://evil.com/image.png Referrer: https://myapp.com/cb?code=xyz

Slide 26

Slide 26 text

26 @leastprivilege Authorization Code Injection GET /authorize ?client_id=app1 &redirect_uri=https://app.com/cb GET /cb?code=stolen client id/secret/stolen access token 3 1 2

Slide 27

Slide 27 text

27 @leastprivilege Mitigation: Proof Key for Code Exchange GET /authorize ?client_id=app1 &redirect_uri=https://app.com/cb &code_challenge=cy..fc GET /cb?code=xyz client id/secret code / code_verifier access token 3 1 2 code_verifier = random number code_challenge = hash(code_verifier)

Slide 28

Slide 28 text

28 @leastprivilege Cross Site Request Forgery • Similar to session fixation attacks – attacker pre-creates code – tries to force victim into same "logon session" GET /cb?code=pre_created_code HTTP/1.1 Host: www.app.com

Slide 29

Slide 29 text

29 @leastprivilege Anti-CSRF • Use state parameter to bind CSRF-Token to user-agent – PKCE helps as well (if enforced) – token can be used to store state locally as well GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=9ad67f13 &redirect_uri=https%3A%2F%2Fwww.app.com%2Fcb associate with some user-agent specific data (session storage, cookie..) GET /cb?code=xyz&state=9ad67f13 Host: www.app.com authorization server must echo back the value

Slide 30

Slide 30 text

30 @leastprivilege Countermeasures Summary • Always do exact matching of redirect URIs • Beware of open redirectors • Callback pages should not contain third-party resources – use Content Security Policy for lock-down • Always use PKCE • Use state parameter to bind request to user-agent • Immediately invalidate state after usage • Immediately invalidate authorization codes after usage • Use rel="noreferrer" and referrer policies

Slide 31

Slide 31 text

31 @leastprivilege MixUp Attack (Variant 1) Attacker AS (A-AS) Honest AS (H-AS) 1. User selects H-AS 6. Client still assumes that A-AS was used and sends code and client secret to A-AS 2. Attacker intercepts request, and changes to A-AS 3. Client stores A-AS selection in user session 4. Attacker changes HTTP response to point to H-AS 5. User authenticates with H-AS – redirects back /login?p=H-AS /login?p=A-AS A-AS 302 A-AS 302 H-AS /cb?code=xyz code + secret 1 2 3 4 5 6 7. Attacker can redeem code 7

Slide 32

Slide 32 text

32 @leastprivilege MixUp Attack (Variant 2) Attacker AS (A-AS) Honest AS (H-AS) 1. User selects A-AS 5. Client sends H-AS code and client secret to A-AS 3. A-AS changes client ID and redirect URI and forwards to H-AS 4. User authenticates with H-AS – redirects back /login?p=A-AS A-AS 302 A-AS /cb?code=xyz code + secret 2. Clients sends user to A-AS to authenticate 1 2 3 4 5

Slide 33

Slide 33 text

33 @leastprivilege MixUp Countermeasures 1. Use AS-specific redirect URIs with exact redirect URI matching 2. Store for each authorization request the intended AS 3. Compare the intended AS with the actual redirect URI where the authorization response was received

Slide 34

Slide 34 text

34 @leastprivilege How does ASP.NET Core prevent MixUp Attacks? • Each external provider is represented by an authentication handler – with a unique name + unique callback endpoint GET /authorize?client_id=mvc&redirect_uri=https://myapp.com/signin-as1 &state=protected(correlationId + other_data) set cookie: correlation.as1.correlationId Challenge (name = as1) Callback GET /signin-as1?code=xyz&state=protected(correlationId + other_data) read cookie: correlation.as1.correlationId

Slide 35

Slide 35 text

35 @leastprivilege Public Clients • Slightly different rules – 1:many mapping of client ID to client instance – public clients cannot store secrets (and thus don’t use them) • IOW no way to authenticate a public client • there are exceptions for certain environments (e.g. trusted hardware) • Native desktop/mobile applications • Browser-based appplications (aka SPAs)

Slide 36

Slide 36 text

36 @leastprivilege Anti Pattern: Native Login Dialogs Username Password Login username/password token token trust Token service API

Slide 37

Slide 37 text

37 @leastprivilege Using a browser with Code Flow + PKCE authentication request render UI & workflow

Slide 38

Slide 38 text

38 @leastprivilege Different Approaches • Choice of browser – embedded web view • private browser & private cookie container – system browser** • e.g. ASAuthenticationSession, Chrome Custom Tabs, or desktop browser • full featured including address bar & add-ins • shared cookie container • Handling the callback – event handling – custom URI schemes – local HTTP listener – "claimed" HTTPS URIs** ** most recommended

Slide 39

Slide 39 text

39 @leastprivilege Token Storage & Management • Typically login workflow only used initially – afterwards refresh tokens are used for "session management" • All tokens should be stored using secure data storage provided by OS – e.g. KeyChain on iOS, DPAPI on Windows… – some support additional security mechanisms (e.g. biometrics) • Tokens can be revoked when not needed anymore – logout – uninstall

Slide 40

Slide 40 text

40 @leastprivilege Browser-based Applications (aka SPAs) • The most problematic client type from a security point of view – but also most popular client type • Unique attacks due to "shared execution environment" nature of browser – Cross-Site Request Forgery (CSRF) – Cross-Site Scripting (XSS) • Two fundamental ways to do API authentication in SPAs – implicit credential that browser sends automatically • cookies, Integrated Windows authentication (Kerberos), X509 client certificates – explicit credential that must be sent from application code • access tokens

Slide 41

Slide 41 text

41 @leastprivilege • Application Server • iniates protocol flow • stores & manages tokens • proxies cross-domain calls • Browser • stores no tokens • uses cookies JavaScript Applications with a Backend JavaScript Applications without a Backend • Browser • initiates flow • store & manages tokens • makes all API calls • use no cookies

Slide 42

Slide 42 text

42 @leastprivilege Same-Site Architecture Browser Front-End Back-End / APIs Identity Provider cookies + anti-forgery https://*.myapp.com external APIs

Slide 43

Slide 43 text

43 @leastprivilege Anti-Forgery Protection • Anti-Forgery Tokens – cookie + header mechanism (e.g. ASP.NET Core MVC) • SameSite Cookies – automatic cookie isolation by site January 2020

Slide 44

Slide 44 text

44 @leastprivilege Access Token Storage in Browsers • No "secure" data storage mechanism in browsers – session storage, local storage, in-memory… – prone to XSS-based attacks • potential exfiltration of tokens • origin-isolation of storage mechanism is a slight improvement • Content Security Policy (CSP) highly recommend – but not always easy – strict dynamic support not widely deployed yet

Slide 45

Slide 45 text

45 @leastprivilege Refresh Token Storage in Browsers • Session-bound token refresh – "silent renew" technique relies on (third party) cookies in iframe • becomes more and more problematic with browser default settings • Unbound refresh tokens are dangerous when stored in browser – MUST rotate refresh tokens on each use, in order to be able to detect a stolen refresh token if one is replayed – SHOULD detect replay of refresh tokens – MUST either set a maximum lifetime on refresh tokens OR expire if the refresh token has not been used within some amount of time

Slide 46

Slide 46 text

46 @leastprivilege OAuth 2.1

Slide 47

Slide 47 text

47 @leastprivilege OAuth 2.1 • RFC 6749 + RFC 6750 + various BCPs == OAuth 2.1 – https://tools.ietf.org/html/draft-parecki-oauth-v2-1 • Most important changes – omission of implicit grant – omission of password grant – PKCE must be used with the authorization code grant – redirect URIs must be compared using exact string matching – refresh tokens must be either sender-constrained or one-time use only – bearer tokens usage omits token in the query string

Slide 48

Slide 48 text

48 @leastprivilege Summary • Some threats can‘t be mitigated (as a developer) – compromise of infrastructure • Some threats are easy to mitigate – CSRF, injection attacks, open redirectors... • Some threats are hard to mitigate – complex setups that specifically target an application • Know your threat/attacker model – implement the mitigations that affect you