OAuth 2.0 has simplified authentication and authorisation for many applications, shifting from custom code to simple library import. However, as more applications come to rely on it, this makes its weaknesses more interesting. An attacker can gain access to a broader set of data via a smaller set of tactics and techniques. First lets understand the threat areas, and then, the best current practices for addressing them.
This is a multi-part blog series. We will cover individual threat areas in 6-parts:
- OAuth 2.0 Threat Model and Security Considerations
- OAuth 2.0 Client Threats
- OAuth 2.0 Authorisation Endpoint Threats
- OAuth 2.0 Token Endpoint Threats
- OAuth 2.0 Refresh Token Threats
- OAuth 2.0 Protected Resource Threats
But first, we will talk about the assumptions and security features of OAuth 2.0. One of the main controversial areas is the reliance on a Bearer Token. In “OAuth 2.0 Proof of Possession” I talked about some of the controversy around this decision. If you leak your Bearer Token, whoever has possession can use it as you without control (until it is revoked or expires). You might lose your Bearer Token through inappropriate logging, through browser cache/cookie/storage manipulation, etc. Its a permanent blank cheque, unprotected from replay. I discussed a new draft standard “OAuth 2.0 Access Token Demonstrate Proof Of Possession” which seeks to reduce this risk by moving to replay-protected model with a new set of cryptographic headers inside the Token.
Much of the protection of OAuth 2.0 comes from the Public Key Infrastrcture which drives TLS, guaranteeing you are talking to who you think, that there is no interception or modification. As such, you should never use OAuth 2.0 without TLS, and, you must never disable certificate checking. In “Let’s Encrypt Staging Safely” I show how to safely use the Let’s Encrypt staging certificates, preventing you from a desire to “turn it all off because It’s just dev mode”. Its all too common to find code which disables CA Certificate checking: don’t let this happen to you.
OAuth 2.0 relies on Client ID and Client Secrets for pairwise authentication to each client. However, for many clients (particularly web-based or mobile-app-based) there is no secure method to store a Client Secret. For these applications you should always use the PKCE Code Flow (not the implicit flow, and not the basic-auth via Client Secret).
The TL;DR of this section, use TLS properly, don’t use Client Secrets is your main take-away.
If we look at the Authorisation Server, we find that it has a host of issues to concern ourself with. Unlike the client this is in a more protected domain of control. Still, this system has usernames, possibly passwords (surely stored encrypted, salted, hashed). It may have plaintext copies of the client secrets. It might even have a plaintext copy of the client refresh token or access token. It also is the server-endpoint of our TLS, so it has a TLS private key. In addition, it is the state transition engine for the OAuth 2.0 dance, meaning if its nonces or states get compromised or are guessable, an attacker can interfect.
Now that we’ve got a background of the basic security underpinnings, let’s dig into the indvidual threats in the next 6 parts.
For more information, the best starting source of information is the IETF RFC 6819 OAuth 2.0 Threat Model and Security Considerations.