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 Implementation for .NET – 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 Agenda 1. Overview of current security guidance 2. Have a closer look at some concrete issues and solutions 3. OAuth future

Slide 4

Slide 4 text

4 @leastprivilege Some Context… 2005 SAML 2.0p 2007 2012 2014 2015 2017 Soon OpenID Connect Session Management OpenID Connect Front-Channel Notifications OpenID Connect Back-Channel Notifications Authentication Method Reference Values OAuth 2.0 Token Exchange OAuth 2.0 Mutual TLS OAuth 2.0 Resource Indicators 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 SAML 2.0 Profile OAuth 2.0 PKCE OAuth 2.0 Security Topics BCP JSON Web Token BCP OAuth 2.0 Threat Model & Security Considerations OAuth 2.0 for Native Apps BCP OAuth 2.0 for Browser-based Applications BCP

Slide 5

Slide 5 text

5 @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/wg/oauth/draft-ietf- oauth-jwt-bcp/ 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 6

Slide 6 text

6 @leastprivilege The Big Picture Browser Native App Server App "Thing" Web App Web API Web API Web API Security Token Service 1 2 1 public client 2 confidential client 1 2 2

Slide 7

Slide 7 text

Simplified Client Resource Owner Resource Server Authorization Server 1 2

Slide 8

Slide 8 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 9

Slide 9 text

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

Slide 10

Slide 10 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 11

Slide 11 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 12

Slide 12 text

12 @leastprivilege

Slide 13

Slide 13 text

13 @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 14

Slide 14 text

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

Slide 15

Slide 15 text

15 @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 16

Slide 16 text

16 @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 17

Slide 17 text

17 @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 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

20 @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 21

Slide 21 text

22 @leastprivilege Sender Constrained Access Tokens w/ MTLS { "iss": "https://issuer", "exp": 1340819380, "nbf": 1340818761, "client_id": "182jmm199", "scope": "api1", "cnf": { "x5t#S256": "bwcK0esc3ACC3DB2Y5_lESsXE8o9ltc05O89jdN-dg2" } }

Slide 22

Slide 22 text

25 @leastprivilege JWTs { "typ": "JWT", "alg": "RS256" "kid": "1" } { "iss": "https://my_issuer", "exp": "1340819380", "aud": [ "invoice.api", "customer.api" ] "client_id": "client1", "sub": "123", "amr" : [ "pwd", "otp" ] } Header Payload

Slide 23

Slide 23 text

26 @leastprivilege JWTs

Slide 24

Slide 24 text

27 @leastprivilege Typed JWTs { "typ": "at+jwt", "alg": "RS256" "kid": "1" } { "iss": "https://my_issuer", "exp": "1340819380", "aud": [ "invoice.api", "customer.api" ] "client_id": "client1", "sub": "123", "amr" : [ "pwd", "otp" ] } Header Payload

Slide 25

Slide 25 text

28 @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 26

Slide 26 text

29 @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 27

Slide 27 text

30 @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 28

Slide 28 text

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

Slide 29

Slide 29 text

32 @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 30

Slide 30 text

35 @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

36 @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

37 @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

38 @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

39 @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

40 @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

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

43 @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

45 @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 40

Slide 40 text

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

Slide 41

Slide 41 text

47 @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 42

Slide 42 text

48 @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 43

Slide 43 text

49 @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 might help • Content Security Policy (CSP) highly recommend – but not always easy – strict dynamic support not widely deployed yet

Slide 44

Slide 44 text

50 @leastprivilege Refresh Token Storage in Browsers • (unconstrained) refresh tokens even more 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 • …or no refresh tokens at all – "silent renew" is a session-bound mechanism to request new access tokens – becomes more and more problematic with browser default settings

Slide 45

Slide 45 text

51 @leastprivilege What's next? • OAuth 2.0 and OpenID Connect move into more specialized and high security/risk scenarios – financial, health care… • Formal analysis shows more potential attack vectors – https://arxiv.org/abs/1901.11520 • Additonal specs are being created to mitigate those attacks – JWT secured authorization requests, rich/pushed authorization requests (RAR/PAR), OAuth.xyz

Slide 46

Slide 46 text

52 @leastprivilege

Slide 47

Slide 47 text

53 @leastprivilege JWT Secured Authorization Requests (JAR) https://tools.ietf.org/wg/oauth/draft-ietf-oauth-jwsreq/ GET /authorize?client_id=client&response_type=code&redirect_uri=https://myapp.com/cb &state=abc&code_challenge=def&scope=openid customer.api GET /authorize?request= eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6ICJzNkJoZF JrcXQzIiwKICAgIC.JhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iL Aog ICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAgICAiY2xpZW 50X2 lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6ICJodHR wczovL2Ns aWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAib3Blbml kIiwKICAgIC JzdGF0ZSI6ICJhZjBpZmpzbGRraiI.sCiAgICAibm9uY2UiOiAibi0wU zZfV3pBMk1q IiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VUElVaPjqW _ToI1yrEJ67BgK b5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC0iQJwXu5Y

Slide 48

Slide 48 text

54 @leastprivilege Request Object { "typ": "oauth.authz.req+jwt", "alg": "RS256", "kid": "1" }. { "iss": "client", "aud": "https://authorizationserver.com", "response_type": "code", "client_id": "client", "redirect_uri": "https://myapp.com/cb", "scope": "openid customer.api", "state": "abc", "code_challenge": "def" }. [Signature]

Slide 49

Slide 49 text

58 @leastprivilege Pushed Authorization Requests (1) • Adds an initial authenticated back-channel call – returns a request object reference https://tools.ietf.org/html/draft-lodderstedt-oauth-par-01 POST /par client_id=client& response_type=code& redirect_uri=https://myapp.com/cb& state=abc& code_challenge=def& authorization_details={…} HTTP/1.1 201 Created { "request_uri": "urn:par:bwc4JK-cc191e-Y1LTC2", "expires_in": 90 }

Slide 50

Slide 50 text

59 @leastprivilege Pushed Authorization Requests (2) • Front-channel only used to transmit reference to authenticated and validated request object GET /authorize?request_uri=urn:par:bwc4JK-cc191e-Y1LTC2

Slide 51

Slide 51 text

60 @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

Slide 52

Slide 52 text

61 @leastprivilege Thanks! …and (because I always forget) - we have stickers!