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

OAuth 2: What could possibly go wrong?

Avatar for Neil Madden Neil Madden
December 06, 2018

OAuth 2: What could possibly go wrong?

Presentation given at Bristech 2018 in Bristol, UK. I discuss various potential security issues to be considered when implementing OAuth 2.0 as a resource server and for clients on mobile, server-side and client-side javascript (single page apps). The talk covers the latest best common practice advice currently in development at the IETF OAuth Working Group, including potential deprecation of the implicit flow in favour of authorization code + PKCE.

Avatar for Neil Madden

Neil Madden

December 06, 2018

Other Decks in Programming

Transcript

  1. Copyright © 2018 ForgeRock. All rights reserved What is OAuth?

    • Original problem: enable 3rd party apps/sites to access my data without giving them my password
  2. Copyright © 2018 ForgeRock. All rights reserved What is OAuth?

    • Original problem: enable 3rd party apps/sites to access my data without giving them my password • OAuth: Protocol for delegated authorisation • OAuth 1 – 2007 (RFC 5849 in 2010) • OAuth 2 – 2012 (RFC 6749)
  3. Copyright © 2018 ForgeRock. All rights reserved What is OAuth?

    • Original problem: enable 3rd party apps/sites to access my data without giving them my password • OAuth: Protocol for delegated authorisation • OAuth 1 – 2007 (RFC 5849 in 2010) • OAuth 2 – 2012 (RFC 6749) • Now: • Lots of extensions • Used outside of Web – mobile, IoT, microservices • Uses beyond delegated authZ – OpenID Connect, UMA
  4. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) wants to use Resource Server (RS)
  5. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) wants to use Resource Server (RS) to access
  6. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) Resource Server (RS) Authorization Server (AS)
  7. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) Resource Server (RS) Authorization Server (AS) Request
 access (scope)
  8. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) Resource Server (RS) Authorization Server (AS) Request
 access (scope) Authorize access
  9. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) Resource Server (RS) Authorization Server (AS) Access token
  10. Copyright © 2018 ForgeRock. All rights reserved The Dance Client

    Resource Owner (RO) Resource Server (RS) Authorization Server (AS) Access token
  11. Copyright © 2018 ForgeRock. All rights reserved OAuth 2 flows

    • Implicit flow – access token returned directly from authorization request (redirect) • In fragment ...#access_token=LGqTQrz71J8... • Purely redirect-based
  12. Copyright © 2018 ForgeRock. All rights reserved OAuth 2 flows

    • Implicit flow – access token returned directly from authorization request (redirect) • In fragment ...#access_token=LGqTQrz71J8... • Purely redirect-based • Authorization code flow – a one-time code is returned • Client makes direct call to AS to swap code for access token • AS can directly authenticate the client
  13. Copyright © 2018 ForgeRock. All rights reserved OAuth 2 flows

    • Implicit flow – access token returned directly from authorization request (redirect) • In fragment ...#access_token=LGqTQrz71J8... • Purely redirect-based • Authorization code flow – a one-time code is returned • Client makes direct call to AS to swap code for access token • AS can directly authenticate the client • Refresh token flow • Previously authorized client • Get new access token without bothering user, extend access
  14. Copyright © 2018 ForgeRock. All rights reserved Where to put

    the access token • 4 main choices (for HTTP): • In URL parameter: ?access_token=LGqTQrz71J8... • In Cookie: Cookie: accesstoken=LGqTQrz71J8... • In POST body (form/x-www-form-urlencoded) • In a header
  15. Copyright © 2018 ForgeRock. All rights reserved Where to put

    the access token • 4 main choices (for HTTP): • In URL parameter: ?access_token=LGqTQrz71J8... • In Cookie: Cookie: accesstoken=LGqTQrz71J8... • In POST body (form/x-www-form-urlencoded) • In a header • URL parameter – bad! • Leaks in access logs of servers, proxies, and Referer header
  16. Copyright © 2018 ForgeRock. All rights reserved Where to put

    the access token • 4 main choices (for HTTP): • In URL parameter: ?access_token=LGqTQrz71J8... • In Cookie: Cookie: accesstoken=LGqTQrz71J8... • In POST body (form/x-www-form-urlencoded) • In a header • URL parameter – bad! • Leaks in access logs of servers, proxies, and Referer header • Cookie – beware CSRF, cookie hijacking, cookie blocking
  17. Copyright © 2018 ForgeRock. All rights reserved Where to put

    the access token • 4 main choices (for HTTP): • In URL parameter: ?access_token=LGqTQrz71J8... • In Cookie: Cookie: accesstoken=LGqTQrz71J8... • In POST body (form/x-www-form-urlencoded) • In a header • URL parameter – bad! • Leaks in access logs of servers, proxies, and Referer header • Cookie – beware CSRF, cookie hijacking, cookie blocking • POST body – better, but mixes authorization with application data
  18. Copyright © 2018 ForgeRock. All rights reserved Authorization: Bearer POST

    /api/foo HTTP/1.1 Authorization: Bearer LGqTQrz71J8... ... HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer scope=”foo bar”
  19. Copyright © 2018 ForgeRock. All rights reserved Authorization: Bearer POST

    /api/foo HTTP/1.1 Authorization: Bearer LGqTQrz71J8... ... HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer scope=”foo bar” • Standard approach (RFC 6750)
  20. Copyright © 2018 ForgeRock. All rights reserved Authorization: Bearer POST

    /api/foo HTTP/1.1 Authorization: Bearer LGqTQrz71J8... ... HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer scope=”foo bar” • Standard approach (RFC 6750) • Middle-boxes, caches all know about Authorization headers
  21. Copyright © 2018 ForgeRock. All rights reserved Authorization: Bearer POST

    /api/foo HTTP/1.1 Authorization: Bearer LGqTQrz71J8... ... HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer scope=”foo bar” • Standard approach (RFC 6750) • Middle-boxes, caches all know about Authorization headers • Triggers same-origin policy/CORS protections in browsers
  22. Copyright © 2018 ForgeRock. All rights reserved How to validate

    an access token? • Scope: up to the RS – what makes sense to the user?
  23. Copyright © 2018 ForgeRock. All rights reserved How to validate

    an access token? • Scope: up to the RS – what makes sense to the user? • Validation unspecified: up to the AS and RS to agree • But see Token Introspection (RFC 7662)
  24. Copyright © 2018 ForgeRock. All rights reserved How to validate

    an access token? • Scope: up to the RS – what makes sense to the user? • Validation unspecified: up to the AS and RS to agree • But see Token Introspection (RFC 7662) • Popular choice: • access token is a signed JWT • can be verified by RS alone
  25. Copyright © 2018 ForgeRock. All rights reserved How to validate

    an access token? • Scope: up to the RS – what makes sense to the user? • Validation unspecified: up to the AS and RS to agree • But see Token Introspection (RFC 7662) • Popular choice: • access token is a signed JWT • can be verified by RS alone • But... what about revocation?
  26. Copyright © 2018 ForgeRock. All rights reserved How to validate

    an access token? • Scope: up to the RS – what makes sense to the user? • Validation unspecified: up to the AS and RS to agree • But see Token Introspection (RFC 7662) • Popular choice: • access token is a signed JWT • can be verified by RS alone • But... what about revocation? • Answer: • Short-lived access tokens • Client must refresh frequently
  27. Copyright © 2018 ForgeRock. All rights reserved The fallacy of

    the short attack window • How short should access token lifetime be? • Minutes? • Hours?
  28. Copyright © 2018 ForgeRock. All rights reserved The fallacy of

    the short attack window • How short should access token lifetime be? • Minutes? • Hours? • Facebook “View As” OAuth attack in September • 50 million accounts affected • 90 million access tokens revoked afterwards • Highly automated
  29. Copyright © 2018 ForgeRock. All rights reserved The fallacy of

    the short attack window • How short should access token lifetime be? • Minutes? • Hours? • Facebook “View As” OAuth attack in September • 50 million accounts affected • 90 million access tokens revoked afterwards • Highly automated • How long was each compromised token used for? • Seconds? Milliseconds?
  30. Copyright © 2018 ForgeRock. All rights reserved The fallacy of

    the short attack window • How short should access token lifetime be? • Minutes? • Hours? • Facebook “View As” OAuth attack in September • 50 million accounts affected • 90 million access tokens revoked afterwards • Highly automated • How long was each compromised token used for? • Seconds? Milliseconds? • Short life-times should not be primary protection measure
  31. Copyright © 2018 ForgeRock. All rights reserved What did we

    forget? • Does the Resource Owner themselves have permission?
  32. Copyright © 2018 ForgeRock. All rights reserved What did we

    forget? • Does the Resource Owner themselves have permission? • Remember: OAuth is delegated authorization
  33. Copyright © 2018 ForgeRock. All rights reserved What did we

    forget? • Does the Resource Owner themselves have permission? • Remember: OAuth is delegated authorization • Assumes RS already has an authorization policy for users
  34. Copyright © 2018 ForgeRock. All rights reserved What did we

    forget? • Does the Resource Owner themselves have permission? • Remember: OAuth is delegated authorization • Assumes RS already has an authorization policy for users • AS doesn’t know anything about the RS during “authorization” call
  35. Copyright © 2018 ForgeRock. All rights reserved What did we

    forget? • Does the Resource Owner themselves have permission? • Remember: OAuth is delegated authorization • Assumes RS already has an authorization policy for users • AS doesn’t know anything about the RS during “authorization” call • Related: does the RO still have permission? • Access tokens with refresh can live a long time • Classic TOCTOU bug
  36. Copyright © 2018 ForgeRock. All rights reserved What did we

    forget? • Does the Resource Owner themselves have permission? • Remember: OAuth is delegated authorization • Assumes RS already has an authorization policy for users • AS doesn’t know anything about the RS during “authorization” call • Related: does the RO still have permission? • Access tokens with refresh can live a long time • Classic TOCTOU bug • OAuth not a replacement for authorization (but see UMA)
  37. Copyright © 2018 ForgeRock. All rights reserved Mobile clients -

    old approach • Register with AS as public client
  38. Copyright © 2018 ForgeRock. All rights reserved Mobile clients -

    old approach • Register with AS as public client • Use a custom URL scheme for redirect: • com.example.app:/callback • OS will handover to your app when redirect occurs
  39. Copyright © 2018 ForgeRock. All rights reserved Mobile clients -

    old approach • Register with AS as public client • Use a custom URL scheme for redirect: • com.example.app:/callback • OS will handover to your app when redirect occurs • Use implicit flow
  40. Copyright © 2018 ForgeRock. All rights reserved Mobile clients -

    old approach • Register with AS as public client • Use a custom URL scheme for redirect: • com.example.app:/callback • OS will handover to your app when redirect occurs • Use implicit flow • Spawn in-app embedded web view
  41. Copyright © 2018 ForgeRock. All rights reserved What’s wrong with

    this approach? Genuine App Authorization Server my-app:/cb?access_token=...
  42. Copyright © 2018 ForgeRock. All rights reserved What’s wrong with

    this approach? • Custom URL schemes are not enforced unique Genuine App Authorization Server my-app:/cb?access_token=...
  43. Copyright © 2018 ForgeRock. All rights reserved What’s wrong with

    this approach? • Custom URL schemes are not enforced unique • Malicious app can register same scheme Genuine App Malicious App Authorization Server my-app:/cb?access_token=...
  44. Copyright © 2018 ForgeRock. All rights reserved What’s wrong with

    this approach? • Custom URL schemes are not enforced unique • Malicious app can register same scheme • Either app could get handed the access token Genuine App Malicious App Authorization Server my-app:/cb?access_token=...
  45. Copyright © 2018 ForgeRock. All rights reserved What’s wrong with

    this approach? • Custom URL schemes are not enforced unique • Malicious app can register same scheme • Either app could get handed the access token • In-app web view: encourages poor practices Genuine App Malicious App Authorization Server my-app:/cb?access_token=...
  46. Copyright © 2018 ForgeRock. All rights reserved Recommendations • Use

    system browser to initiate flows Image: https://www.flickr.com/photos/79908182@N00/4154193182 (user: smoorenburg, CC-BY-2.0)
  47. Copyright © 2018 ForgeRock. All rights reserved Recommendations • Use

    system browser to initiate flows • Use claimed HTTPS redirects • iOS: Universal Links • Android: App Links Image: https://www.flickr.com/photos/79908182@N00/4154193182 (user: smoorenburg, CC-BY-2.0)
  48. Copyright © 2018 ForgeRock. All rights reserved Recommendations • Use

    system browser to initiate flows • Use claimed HTTPS redirects • iOS: Universal Links • Android: App Links • Use the authorization code flow... Image: https://www.flickr.com/photos/79908182@N00/4154193182 (user: smoorenburg, CC-BY-2.0)
  49. Copyright © 2018 ForgeRock. All rights reserved Recommendations • Use

    system browser to initiate flows • Use claimed HTTPS redirects • iOS: Universal Links • Android: App Links • Use the authorization code flow... • ... with PKCE (RFC 7636) Image: https://www.flickr.com/photos/79908182@N00/4154193182 (user: smoorenburg, CC-BY-2.0)
  50. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS)
  51. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Generate random verifier, v
  52. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Request authorization
 code_challenge=SHA-256(v)
  53. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Authorize as normal
  54. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Authorization code
  55. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Request access token
 code=<code>&
 code_verifier=<v>
  56. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Request access token
 code=<code>&
 code_verifier=<v> Check SHA-256(v) = challenge
  57. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Access token
  58. Copyright © 2018 ForgeRock. All rights reserved PKCE: Proof Key

    for Code Exchange Resource Owner (RO) Client Resource Server (RS) Authorization Server (AS) Access token
  59. Copyright © 2018 ForgeRock. All rights reserved Server-side clients •

    Use authorization code flow • Confidential client, so require authentication to AS
  60. Copyright © 2018 ForgeRock. All rights reserved Server-side clients •

    Use authorization code flow • Confidential client, so require authentication to AS • What can go wrong?
  61. Copyright © 2018 ForgeRock. All rights reserved Server-side clients •

    Use authorization code flow • Confidential client, so require authentication to AS • What can go wrong? • Credential theft • Client secret recoverable from AS • Consider private_key_jwt or mTLS authentication
  62. Copyright © 2018 ForgeRock. All rights reserved Server-side clients •

    Use authorization code flow • Confidential client, so require authentication to AS • What can go wrong? • Credential theft • Client secret recoverable from AS • Consider private_key_jwt or mTLS authentication • Code injection attack (replay) • Use PKCE on server-side too! • (But quite difficult attack model if using state properly)
  63. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    /spa#access_token=LGqTQrz71J8... Web Page Legitimate
 Script
  64. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    • Old advice: use implicit flow /spa#access_token=LGqTQrz71J8... Web Page Legitimate
 Script
  65. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    • Old advice: use implicit flow • What can go wrong? /spa#access_token=LGqTQrz71J8... Web Page Legitimate
 Script
  66. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    • Old advice: use implicit flow • What can go wrong? • Token sniffing from URL /spa#access_token=LGqTQrz71J8... Web Page Legitimate
 Script Malicious
 Script
  67. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    • Old advice: use implicit flow • What can go wrong? • Token sniffing from URL • Referer leaks (document.referrer in iframe) • But fragment not usually included /spa#access_token=LGqTQrz71J8... Web Page Legitimate
 Script Malicious
 Script
  68. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    • Old advice: use implicit flow • What can go wrong? • Token sniffing from URL • Referer leaks (document.referrer in iframe) • But fragment not usually included • Token injection Web Page Legitimate
 Script Malicious
 Script /spa#access_token=Kt8Fc98cDE...
  69. Copyright © 2018 ForgeRock. All rights reserved Client-side web apps/SPAs

    • Old advice: use implicit flow • What can go wrong? • Token sniffing from URL • Referer leaks (document.referrer in iframe) • But fragment not usually included • Token injection • Redirects include fragment Web Page Legitimate
 Script Malicious
 Script /spa#access_token=Kt8Fc98cDE...
  70. Copyright © 2018 ForgeRock. All rights reserved New advice for

    SPAs • One big change since OAuth 2.0 published (2012):
  71. Copyright © 2018 ForgeRock. All rights reserved New advice for

    SPAs • One big change since OAuth 2.0 published (2012): • CORS! • Published in 2014
  72. Copyright © 2018 ForgeRock. All rights reserved New advice for

    SPAs • One big change since OAuth 2.0 published (2012): • CORS! • Published in 2014 • Previously not possible for SPA to make cross-origin call to AS
  73. Copyright © 2018 ForgeRock. All rights reserved New advice for

    SPAs • One big change since OAuth 2.0 published (2012): • CORS! • Published in 2014 • Previously not possible for SPA to make cross-origin call to AS • CORS changes that – allows SPA to use authorization code flow
  74. Copyright © 2018 ForgeRock. All rights reserved New advice for

    SPAs • One big change since OAuth 2.0 published (2012): • CORS! • Published in 2014 • Previously not possible for SPA to make cross-origin call to AS • CORS changes that – allows SPA to use authorization code flow • New advice: auth code + PKCE • Public client, just like for mobile
  75. Copyright © 2018 ForgeRock. All rights reserved Can’t move off

    implicit? • Don’t Panic! • The sky isn’t falling • Web security best practice goes a long way
  76. Copyright © 2018 ForgeRock. All rights reserved Can’t move off

    implicit? • Don’t Panic! • The sky isn’t falling • Web security best practice goes a long way • Mitigations:
  77. Copyright © 2018 ForgeRock. All rights reserved Can’t move off

    implicit? • Don’t Panic! • The sky isn’t falling • Web security best practice goes a long way • Mitigations: • Use OpenID Connect flows • ID Token includes “at_hash”, “nonce” – prevents injection • Consider even if you don’t care about authentication
  78. Copyright © 2018 ForgeRock. All rights reserved Can’t move off

    implicit? • Don’t Panic! • The sky isn’t falling • Web security best practice goes a long way • Mitigations: • Use OpenID Connect flows • ID Token includes “at_hash”, “nonce” – prevents injection • Consider even if you don’t care about authentication • JARM – JWT-secure Authorization Response Mode
  79. Copyright © 2018 ForgeRock. All rights reserved Can’t move off

    implicit? • Don’t Panic! • The sky isn’t falling • Web security best practice goes a long way • Mitigations: • Use OpenID Connect flows • ID Token includes “at_hash”, “nonce” – prevents injection • Consider even if you don’t care about authentication • JARM – JWT-secure Authorization Response Mode • Sender-constrained access tokens (PoP)
  80. Copyright © 2018 ForgeRock. All rights reserved Take-aways • Prefer

    the authorization code flow in all cases • Even for SPAs • Implicit likely to be deprecated
  81. Copyright © 2018 ForgeRock. All rights reserved Take-aways • Prefer

    the authorization code flow in all cases • Even for SPAs • Implicit likely to be deprecated • Use PKCE • Even for confidential clients
  82. Copyright © 2018 ForgeRock. All rights reserved Take-aways • Prefer

    the authorization code flow in all cases • Even for SPAs • Implicit likely to be deprecated • Use PKCE • Even for confidential clients • Prefer Authorization: Bearer
  83. Copyright © 2018 ForgeRock. All rights reserved Take-aways • Prefer

    the authorization code flow in all cases • Even for SPAs • Implicit likely to be deprecated • Use PKCE • Even for confidential clients • Prefer Authorization: Bearer • Security drafts in progress: • draft-ietf-oauth-security-topics • draft-parecki-oauth-browser-based-apps