OAuth security best practices
The attacks in this series were not discovered all at once. They were found over the years after OAuth 2.0 was published, in research and in real incidents, and the defenses were written down as they were understood. The OAuth 2.0 Security Best Current Practice, published as RFC 9700 in January 2025, collects them. It updates the original specification, the bearer token specification, and the original threat model, and it turns several defenses that were once optional into requirements.
Most of its advice has appeared in earlier lessons, one attack at a time. Read by role, it becomes a short list for each party. The document separates what a party must do from what it should or may do, and the tables below keep those words. Advice phrased without them comes from the earlier lessons.
Practices for clients
| Practice | Explained in |
|---|---|
Public clients must use PKCE, and it is recommended for confidential clients. Clients should use the S256 method. | PKCE; Code interception and injection |
| The password grant must not be used, and the implicit grant should not be. | Choosing a flow |
| Clients must prevent forged callbacks, with one-time state bound to the browser session, or with PKCE once they have confirmed that the server enforces it. | Correlating requests and responses; Request correlation and CSRF |
A client working with more than one authorization server must defend against mix-up, and should do so by checking iss. | Authorization server mix-up |
| Clients must not run open redirects. The callback page should not include third-party resources or links to other sites. | Redirects and authorization codes; Redirect URI validation |
| Clients must not send access tokens in a URL query parameter. Send each token only to the API it was issued for. | Using access tokens; Token theft and replay |
| Request only the access the task needs. | Grants, scopes, and consent; Scopes and audiences |
| Refresh tokens must be kept confidential in storage. Under rotation, run one refresh at a time. | Server-rendered web applications; The refresh token grant; Refresh token theft |
The guidance also recommends that authorization servers publish metadata and that clients configure themselves from it where it exists, which reduces the chance of a mistyped or attacker-supplied endpoint.
Practices for resource servers
| Practice | Explained in |
|---|---|
| Validate every token completely. The API must refuse any token not issued for it. | Token formats and validation; Scopes and audiences |
| Check scope and access to the specific object on every request, and never treat a token issued to a client acting for itself as a person's token. | Enforcing access at an API |
| The API must treat received tokens like other sensitive secrets, never storing or passing them on in plain form, which also keeps them out of logs. | Token theft and replay |
| APIs should use sender-constrained tokens. When a token is bound, verify the proof of possession on each request. | Token theft and replay |
Underneath all three roles sits transport security. Authorization responses must never travel over unencrypted connections, which is why the loopback exception is the only place http appears. Between client and API, the guidance recommends TLS from end to end. When a proxy ends the TLS connection in front of an API, it must sanitize every incoming header the API relies on for security, such as a forwarded client certificate or address, so an outside caller cannot supply a forged one, and the connection from the proxy to the API must be protected too.
From best practice to OAuth 2.1
Many of these rules change defaults rather than add features, so the OAuth working group has been folding them into the framework itself. OAuth 2.1, a revision the working group began as an Internet-Draft, consolidates OAuth 2.0 with PKCE, the guidance for native and browser applications, bearer token usage, and this best current practice. In it, the code flow includes PKCE by default, redirect URIs are compared exactly, the implicit and password grants are left out, tokens never appear in query strings, and public clients' refresh tokens must be sender-constrained or used only once.
Because OAuth 2.1 gathers existing guidance rather than inventing new mechanisms, a deployment that follows the original specification together with RFC 9700, as the tables above do, already behaves as OAuth 2.1 describes in most respects. The mechanisms those tables kept pointing toward, such as sender-constrained tokens, issuer identification, and server metadata, belong to Advanced OAuth, which takes the extensions one at a time. It begins with the authorization request itself, which every redirect-based flow so far has sent through the browser, where anyone along the way can read or alter it.