Securing Microservices with OAuth 2 und OpenID Connect

OWASP Chapter Munich 30.4.2019

Slides: https://andifalk.github.io/owasp-chapter-munich-04-2019
Demos: https://github.com/andifalk/owasp-chapter-munich-04-2019

Andreas Falk

Novatec Consulting GmbH

andreas.falk@novatec-gmbh.de / @andifalk (Twitter)

https://www.novatec-gmbh.de

Agenda

Intro to OAuth 2.0 & OpenID Connect 1.0

4th OAuth Security Workshop 2019

OAuth 2 & OIDC with Spring Security (Live Demo)

Discussion

OAuth 2.0

101

RFC 6749: The OAuth 2.0 Authorization Framework
RFC 6750: OAuth 2.0 Bearer Token Usage
RFC 6819: OAuth 2.0 Threat Model and Security Considerations

What is OAuth 2.0?

OAuth 2.0 is an authorization delegation framework

OAuth 2.0 Model

OAuth 2.0 Grant Flows

Client Type Flow Refresh Tokens
Confidential Authorization Code X
Public (Native) Authorization Code (PKCE) X
Public (SPA) Implicit --
Trusted RO Password Creds X
No Resource Owner Client Credentials --

Authorization Code Grant Flow

Authorization Request

GET https://authserver.example.com/authorize

?response_type=code

&client_id=abcdefg

&redirect_uri=https://client.abc.com/callback

&scope=api.read api.write

&state=xyz

Authorization Response

HTTP/1.1 302 Found

Location: https://client.abc.com/callback

?code=ab23bhW56Xb

&state=xyz

Token Request (Basic Auth)

Client-Id=123, Client-Secret=456, Base64(123:456)="MTIzOjQ1Ng=="

POST https://authserver.example.com/token

Content-Type:
application/x-www-form-urlencoded

Authorization: Basic MTIzOjQ1Ng==

 

grant_type=authorization_code&code=ab23bhW56Xb

&redirect_uri=https://client.abc.com/callback

Token Request (Body)

Client-Id=123, Client-Secret=456

POST https://authserver.example.com/token

Content-Type:
application/x-www-form-urlencoded

 

grant_type=authorization_code&code=ab23bhW56Xb

&redirect_uri=https://client.abc.com/callback

&client_id=123&client_secret=456

Token Response


                             HTTP/1.1 200 OK
                             Content-Type: application/json;charset=UTF-8

                             {
                               "access_token":"2YotnFZFEjr1zCsicMWpAA",
                               "token_type":"bearer",
                               "expires_in":3600,
                               "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
                             }
                        

Implicit Grant Flow

Authorization Request

GET https://authserver.example.com/authorize

?response_type=token

&client_id=abcdefg

&redirect_uri=https://client.abc.com/callback

&scope=api.read api.write

&state=xyz

Authorization Response

HTTP/1.1 302 Found

Location: https://client.abc.com/callback

#access_token=2YotnFZFEjr1zCsicMWpAA

&token_type=bearer

&expires_in=3600

&scope=api.read api.write

&state=xyz

Further OAuth 2.0 Standards

RFC 7636: Proof Key for Code Exchange (“Pixy”)

RFC 7662: Token Introspection

RFC 7009: Token Revocation

OpenID Connect 1.0

(OIDC)

101

OpenID Connect Core 1.0
OpenID Connect Dynamic Client Registration 1.0
OpenID Connect Discovery 1.0

OpenID Connect 1.0 is for Authentication

OAuth 2.0 is not an authentication protocol

OIDC Model

Additions to OAuth 2.0

Id Token (JWT format)

User Info Endpoint

Standard Scopes

Hybrid Grant Flow

OpenID Provider Configuration Information

ID Token

JSON Web token (JWT)

Base 64 Encoded JSON Formatted Value of...

...Header

...Payload

...Signature


                            GET / HTTP/1.1
                            Host: localhost:8080
                            Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N...
                        

JSON Web Token (JWT)

Header


                            {
                              typ: "JWT",
                              alg: "RS256"
                            }
                        

Payload


                            {
                              iss: "https://identity.example.com",
                              aud: "my-client-id",
                              exp: 1495782385,
                              nonce: "N0.46824857243233511495739124749",
                              iat: 1495739185,
                              at_hash: "hC1NDSB8WZ9SnjXTid175A",
                              sub: "mysubject",
                              auth_time: 1495739185,
                              email: "test@gmail.com"
                            }
                        

ID Token Claims

Scope Required Description
iss X Issuer Identifier
sub X Subject Identifier
aud X Audience(s) of this ID Token
exp X Expiration time
iat X Time at which the JWT was issued
auth_time (X) Time of End-User authentication
nonce -- Associate a client with an ID Token

Token Validation

User Info Endpoint


                            GET /userinfo HTTP/1.1
                            Host: identityserver.example.com
                            Authorization: Bearer SlAV32hkKG
                        

                            HTTP/1.1 200 OK
                            Content-Type: application/json

                            {
                             "sub": "248289761001",
                             "name": "Jane Doe",
                             "given_name": "Jane",
                             "family_name": "Doe",
                             "preferred_username": "j.doe",
                             "email": "janedoe@example.com",
                             "picture": "http://example.com/janedoe/me.jpg"
                            }
                        

OIDC Flows

  • Authorization Code (w/ or w/o PKCE)
  • Implicit
  • Hybrid

OpenID Connect 1.0 Configuration

https://example.com/.well-known/openid-configuration


                            {
                              "authorization_endpoint": "https://idp.example.com/auth",
                              "grant_types_supported": [
                                  "authorization_code",
                                  "implicit",
                                  "refresh_token"
                              ],
                              "issuer": "https://idp.example.com",
                              "jwks_uri": "https://idp.example.com/keys",
                              "token_endpoint": "https://idp.example.com/token",
                              "userinfo_endpoint": "https://idp.example.com/userinfo",
                              ...
                            }
                        

OpenID Connect Discovery 1.0

4th OAuth Security Workshop 2019

Stuttgart

https://sec.uni-stuttgart.de/events/osw2019


https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926

Lots of discussions and comments

OAuth 2.0 Security Best Current Practice

Torsten Lodderstedt and Daniel Fett

OAuth 2.0 Security Best Current Practice

Implicit Flow Attacks


Source: Torsten Lodderstedt and Daniel Fett

OAuth 2.0 for Browser-Based Apps

David Waite (PingFederate)

OAuth 2.0 for Browser-Based Apps

OAuth 2.0 for Browser-Based Apps

Content-Security Policy

Use a unique redirect URI

NOT issue refresh tokens

OAuth 2.0 for Browser-Based Apps

Other Known OAuth 2.0 Attacks

  • Lack of CSRF protection
  • Authorization code leakage and replay
  • Authorization code injection
  • Open Re-directors
  • State leakage and replay
  • Insufficient Redirect URI matching
  • Too powerful access tokens
  • Mix-Up Attacks

Open Redirect !!

“OAuth 2.1” Grant Flows

Client Type Flow Refresh Tokens
Confidential Authorization Code (PKCE) X
Public (Native) Authorization Code (PKCE) X
Public (SPA) Authorization Code (PKCE) --
Trusted RO Password Creds X
No Resource Owner Client Credentials --

Proof Key for Code Exchange by OAuth Public Clients (PKCE)

(“Pixy”)

Mitigates authorization code attacks

Mitigates token leakage in SPAs

Proof Key for Code Exchange by OAuth Public Clients

PKCE - Authorization Request

GET https://authserver.example.com/authorize

?response_type=code

&client_id=abcdefg

&redirect_uri=https://client.abc.com/callback

&scope=api.read api.write

&state=xyz

&code_challenge=xyz...&code_challenge_method=S256

PKCE - Token Request

Client-Id=123, Client-Secret=456

POST https://authserver.example.com/token

Content-Type:
application/x-www-form-urlencoded

grant_type=authorization_code&code=ab23bhW56Xb

&redirect_uri=https://client.abc.com/callback

&client_id=123&client_secret=456

&code_verifier=4gth4jn78k_8

Steal Tokens via XSS

“XSS is Game-Over for OAuth 2” (Jim Manico)

OAuth 2 Access Token JWT Profile

Vittorio Bertocci (Auth0)

JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens

OAuth 2 Access Token JWT Profile

Required claims: iss, exp, aud, sub, client_id

Consider privacy restrictions for identity claims

Authorization claims according to SCIM Core (RFC7643):

  • Groups
  • Entitlements
  • Roles

System for Cross-domain Identity Management (SCIM)

Token Binding

RFC8471: The Token Binding Protocol Version 1.0

RFC8472: (TLS) Extension for Token Binding Protocol Negotiation

RFC8473: Token Binding over HTTP

OAuth 2.0 Mutual TLS Client Authentication and Certificate-Bound Access Tokens

Google - Intent to Remove: Token Binding

Further Internet-Drafts for OAuth 2

List of OAuth 2 Internet-Drafts (by date)

Demo Time

OAuth 2.0 & OpenID Connect 1.0

With Spring Security 5

“Legacy” Spring Security OAuth 2 Stack

“New” Spring Security
OAuth 2 Stack

Demo application

What's new in

Spring Security 5.2 & 5.3

Spring Security 5.2

Spring Security 5.2.0 M2 GitHub Issues
Spring Security 5.2.0 RC1 GitHub Issues

Book References

Q&A

https://www.novatec-gmbh.de
https://blog.novatec-gmbh.de
andreas.falk@novatec-gmbh.de
Twitter: @andifalk

Online References

All images used are from Pixabay and are published under Creative Commons CC0 license.

All used logos are trademarks of respective companies