Aaron Parecki • @aaronpk
OAuth Security Workshop • May 2022
App Integrity Attestations
as OAuth Client Authentication
Slide 2
Slide 2 text
Public Clients
Confidential Clients
Application running on a server
Has the ability to keep strings secret
since code is running in a trusted environment
The application can't be configured with secrets
JavaScript/Single-Page apps: "view source"
Native apps: decompile and extract strings
Slide 3
Slide 3 text
PKCE
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
POST /token
client_id=XXXXX
&authorization_code=XXXXX
!
Slide 6
Slide 6 text
POST /token
client_id=XXXXX
&client_secret=XXXXX
&authorization_code=XXXXX
?
Slide 7
Slide 7 text
POST /token
client_id=XXXXX
&code_verifier=XXXX
&authorization_code=XXXXX
:-)
Slide 8
Slide 8 text
PKCE was recommended for mobile
apps, which can’t use a secret
Mobile apps can’t be
deployed with a client secret
Slide 12
Slide 12 text
example://redirect?
code=AUTHORIZATION_CODE_HERE&
state=1234zyx
https://app.example.com?
code=AUTHORIZATION_CODE_HERE&
state=1234zyx
Custom URL Scheme
App-Claimed URL Pattern
Redirect URLs in Mobile Apps
Slide 13
Slide 13 text
Neither of these is perfect
Slide 14
Slide 14 text
POST https://api.authorization-server.com/token
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID&
code_verifier=VERIFIER_STRING
Nothing here authenticates the app.
It’s possible to impersonate any native app with its client_id.
Authorization Code Exchange (with PKCE)
Slide 15
Slide 15 text
Redirect URL registration
+ app-claimed URL patterns
More or less protects against authorization
code interception by malicious apps
Does nothing to protect against app impersonation
Slide 16
Slide 16 text
Why is app impersonation
a problem?
Slide 17
Slide 17 text
It may or may not be a
problem for you
Slide 18
Slide 18 text
Some systems give additional privileges
to apps based on their client_id
• bypass the consent screen
• access private API methods
• higher rate limits
Slide 19
Slide 19 text
Where else is app impersonation
a problem?
Slide 20
Slide 20 text
High score leaderboards
Player 1 9000
Player 4 7800
Player 2 4495
Player 8 2100
Player 5 700
Slide 21
Slide 21 text
POST https://api.game-server.example/score
display_name=Hacker&
score=99999999
Mobile game reports new high score
Slide 22
Slide 22 text
Does OAuth solve this?
Slide 23
Slide 23 text
Not really!
Slide 24
Slide 24 text
POST https://api.game-server.example/score
Authorization: Bearer XXXXXXXXXXXX
score=99999999
Mobile game reports new high score with an access token
Slide 25
Slide 25 text
App Integrity
Slide 26
Slide 26 text
“Is this request to the server being made by
a legitimate instance of my application?”
Slide 27
Slide 27 text
…create a hardware-
based, cryptographic
key that uses Apple
servers to certify that the
key belongs to a valid
instance of your app.
https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity
Slide 28
Slide 28 text
Apple App Attestation
https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity
Version Support
DCAppAttestService
iOS 14
2020
Google Play Integrity API
(Replaces SafetyNet)
Unknown
Launched in 2021
Slide 42
Slide 42 text
How do we apply this to OAuth?
Slide 43
Slide 43 text
No content
Slide 44
Slide 44 text
No content
Slide 45
Slide 45 text
Should assertion happen at:
• Install time (dynamic client registration)
• On every authentication (at the token endpoint)
• At every high-value API call (resource server)
Slide 46
Slide 46 text
iOS Questions
• Apple suggests associating a private key with a user account
• To use this as part of the login flow, when should this key get
associated with a user?
• Server stores key before the user logs in?
Slide 47
Slide 47 text
Both Platforms
• A server-generated nonce is required before generating the assertion
• What should the nonce be?
• A separate pre-flight request the app makes before the
authorization code flow starts?
• Require PAR and include an additional parameter in the PAR
response?