OAuth 2.0
In API and identity security, OAuth 2.0 is an authorisation framework that lets an application act on a user’s behalf without handling their password. It does not authenticate the user: that is OpenID Connect, the identity layer built on top of it, and confusing the two is the most common design error in the ecosystem.
How it works
Four parties appear in the specification, RFC 6749. The resource owner is the user. The client is the application asking. The authorisation server issues tokens. The resource server accepts them. The client sends the user to the authorisation server, the user consents to a specific scope, and the client receives an access token that represents that delegated permission rather than the user’s credentials.
Current practice is the authorisation code flow with PKCE, defined in RFC 7636, for every client type including confidential ones. PKCE binds the code to the client instance that started the exchange by requiring a proof of possession at redemption, which removes the value of an intercepted code. The implicit flow, which returned a token straight through the browser, is no longer recommended.
What goes wrong
The framework is used as if it authenticated. An application that treats the possession of an access token as proof of the user’s identity is broken, because the token says an application was granted a permission, not that a particular person is present. The identity assertion comes from OpenID Connect, in the form of an ID token that has an audience and has to be validated as such.
The rest of what we find is redirect handling. A redirect URI matched by prefix or substring rather than exactly lets an attacker append a path they control and receive the code. An open redirect anywhere on a registered host achieves the same. State parameters generated but never checked leave the flow open to being fixed by a third party. Scopes requested broadly and granted permanently mean a low-value integration ends up holding read access to a mailbox indefinitely, which is one of the more useful things we find in a tenant.
Where this shows up in an audit
We test the flow as it is deployed, not as it is documented: which flows the authorisation server still accepts, whether PKCE is enforced or merely supported, how redirect URIs are matched, whether the tokens are validated for audience and issuer at the resource server, and what happens to refresh tokens when a session is revoked. The finding names the parameter and shows the token we obtained. The security best current practice for the framework is worth citing in a remediation section; verify the current document reference before it goes into a report. This is part of how we test delegated access on an API.