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

OAuth and OpenID Connect: Security Best Practices

OAuth and OpenID Connect: Security Best Practices

Dominick Baier

January 24, 2020
Tweet

More Decks by Dominick Baier

Other Decks in Programming

Transcript

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

    View full-size slide

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

    View full-size slide

  3. 3
    @leastprivilege
    Agenda
    1. Overview of current security guidance
    2. Have a closer look at some concrete issues and solutions
    3. OAuth future

    View full-size slide

  4. 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

    View full-size slide

  5. 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/

    View full-size slide

  6. 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

    View full-size slide

  7. Simplified
    Client
    Resource
    Owner
    Resource
    Server
    Authorization
    Server
    1
    2

    View full-size slide

  8. 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)

    View full-size slide

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

    View full-size slide

  10. 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

    View full-size slide

  11. 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

    View full-size slide

  12. 12
    @leastprivilege

    View full-size slide

  13. 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

    View full-size slide

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

    View full-size slide

  15. 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)

    View full-size slide

  16. 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

    View full-size slide

  17. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  20. 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

    View full-size slide

  21. 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"
    }
    }

    View full-size slide

  22. 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

    View full-size slide

  23. 26
    @leastprivilege
    JWTs

    View full-size slide

  24. 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

    View full-size slide

  25. 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

    View full-size slide

  26. 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

    View full-size slide

  27. 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

    View full-size slide

  28. 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

    View full-size slide

  29. 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)

    View full-size slide

  30. 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

    View full-size slide

  31. 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

    View full-size slide

  32. 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

    View full-size slide

  33. 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

    View full-size slide

  34. 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

    View full-size slide

  35. 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)

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  41. 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

    View full-size slide

  42. 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

    View full-size slide

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

    View full-size slide

  44. 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

    View full-size slide

  45. 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

    View full-size slide

  46. 52
    @leastprivilege

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  49. 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
    }

    View full-size slide

  50. 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

    View full-size slide

  51. 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

    View full-size slide

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

    View full-size slide