Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Part 1 - OAuth 2.0 Security Best Practices

Part 1 - OAuth 2.0 Security Best Practices

NDC Oslo 2020


Dominick Baier

June 10, 2020

More Decks by Dominick Baier

Other Decks in Programming


  1. OpenID Connect & OAuth 2.0 Security Best Practices Dominick Baier

  2. 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 dominick.baier@leastprivilege.com blog https://leastprivilege.com twitter @leastprivilege slides https://speakerdeck.com/leastprivilege
  3. 3 @leastprivilege High Security OAuth FAPI https://fapi.openid.net

  4. 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
  5. 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"
  6. 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/
  7. 7 @leastprivilege The Big Picture Browser Native App Server App

    "Thing" Web App Web API Web API Web API Security Token Service
  8. Simplified Client Resource Owner Resource Server Authorization Server 1 2

  9. 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)
  10. Attack Model (2) compromise of an endpoint Client Resource Owner

    Resource Server Authorization Server 1 2 • Client, AS or RS
  11. 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
  12. 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
  13. 13 @leastprivilege

  14. 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
  15. 15 @leastprivilege Implicit Flow Response GET /callback.html #token=32x…133 &expires_in=3600 &token_type=Bearer

  16. 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)
  17. 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
  18. 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
  19. 19 @leastprivilege Grand Unification Application Type Flow Machine to Machine

    Client Credentials Flow Interactive Application Code Flow + PKCE
  20. 20 @leastprivilege Machine to Machine APIs Authorization Server Scopes: api1,

    api2 api3… client_id/client_secret, scope=api1 api2 access token access token
  21. 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
  22. 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
  23. 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
  24. 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
  25. 25 @leastprivilege Credential Leakage via Referrer Headers • Might happen

    on client or authorization server <html> <body> <img src='https://evil.com/image.png' /> </body> </html> GET /some_endpoint?code=xyz GET https://evil.com/image.png Referrer: https://myapp.com/cb?code=xyz
  26. 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
  27. 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)
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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)
  36. 36 @leastprivilege Anti Pattern: Native Login Dialogs Username Password Login

    username/password token token trust Token service API
  37. 37 @leastprivilege Using a browser with Code Flow + PKCE

    authentication request render UI & workflow
  38. 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
  39. 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
  40. 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
  41. 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
  42. 42 @leastprivilege Same-Site Architecture Browser Front-End Back-End / APIs Identity

    Provider cookies + anti-forgery https://*.myapp.com external APIs
  43. 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
  44. 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
  45. 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
  46. 46 @leastprivilege OAuth 2.1

  47. 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
  48. 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