Application Security

OAuth Token Security Throughout the Lifecycle

OAuth tokens grant access to APIs, services, and user data. Their security across creation, storage, use, and revocation determines your application risk posture.

Yukti Singhal
Security Researcher
4 min read

OAuth 2.0 is the standard authorization framework for modern applications. Almost every application that integrates with third-party APIs uses OAuth tokens. These tokens are bearer credentials -- anyone who possesses the token can use it. This makes token security the foundation of your application authorization model.

The OAuth token lifecycle has four phases: creation (token issuance), storage, use (API calls), and revocation. Security failures at any phase compromise the entire system.

Token Creation

Authorization Code Flow

The authorization code flow is the recommended approach for server-side applications. The client receives an authorization code through a browser redirect and exchanges it for tokens through a backend channel.

Use PKCE (Proof Key for Code Exchange). Even for server-side applications, PKCE prevents authorization code interception attacks. It was originally designed for mobile apps but is now recommended for all OAuth clients.

Validate the state parameter. The state parameter prevents CSRF attacks on the OAuth callback endpoint. Generate a cryptographically random state value, store it in the session, and verify it when the callback is received.

Use the most restrictive scopes. Request only the OAuth scopes your application actually needs. An over-scoped token that is stolen grants the attacker broader access than necessary.

Token Types

Access tokens are short-lived (minutes to hours) and used for API calls. Their short lifetime limits the window of exposure if stolen.

Refresh tokens are long-lived and used to obtain new access tokens. They are far more dangerous if stolen because they provide persistent access. Store them with the same care as passwords.

ID tokens (OpenID Connect) contain user identity information. They should not be used for API authorization -- use access tokens for that.

Token Storage

Server-Side Applications

Store tokens in server-side sessions or encrypted databases. Never store tokens in client-accessible locations (cookies without httpOnly, localStorage, URL parameters).

For refresh tokens, encrypt them at rest using a key management service. Tie refresh tokens to the specific client instance that obtained them, so a stolen token cannot be used from a different client.

Single-Page Applications (SPAs)

SPAs have limited secure storage options. The recommended approaches are:

Backend-for-Frontend (BFF) pattern. The SPA communicates with a backend service that handles OAuth flows and stores tokens server-side. The SPA receives a session cookie (httpOnly, secure, sameSite) instead of raw tokens.

In-memory storage. Store access tokens in JavaScript memory (not localStorage or sessionStorage). Tokens are lost on page refresh but cannot be accessed by XSS attacks that read storage. Use refresh token rotation with the BFF pattern for token renewal.

Mobile Applications

Store tokens in the platform secure storage: iOS Keychain or Android KeyStore. These provide hardware-backed encryption that protects tokens even if the device filesystem is compromised.

Token Use

Send tokens in the Authorization header. Use Authorization: Bearer <token> for API calls. Never send tokens as URL query parameters (they end up in server logs, browser history, and referrer headers).

Validate tokens on every request. The API server must verify the token signature, check expiration, validate the audience claim, and confirm the required scopes. Do not cache validation results for longer than the token lifetime.

Implement token binding. Where possible, bind tokens to the client that obtained them. Mutual TLS (mTLS) certificate binding and Demonstrating Proof of Possession (DPoP) prevent stolen tokens from being used by other clients.

Token Revocation

Implement revocation endpoints. Provide a way for users and administrators to revoke tokens immediately. This is especially important for refresh tokens.

Handle refresh token rotation. When a refresh token is used, issue a new refresh token and invalidate the old one. If a revoked refresh token is presented, invalidate all tokens in the chain (this indicates the token was stolen).

Monitor for anomalous token use. Track where tokens are used from (IP address, geography, user agent) and flag anomalous patterns. A token suddenly used from a new country may have been stolen.

Common Mistakes

Storing tokens in localStorage. Any XSS vulnerability in your application can read localStorage, stealing all stored tokens.

Not rotating refresh tokens. Long-lived refresh tokens that never change give attackers indefinite access if stolen.

Accepting expired tokens. Clock skew allowances that are too generous extend the useful life of stolen tokens.

Not validating token audience. A token intended for one API should not be accepted by another. Always validate the aud claim.

How Safeguard.sh Helps

Safeguard.sh monitors the OAuth libraries and authentication frameworks in your dependency tree for known vulnerabilities. Our platform tracks CVEs in popular OAuth libraries, detects insecure token handling patterns in your dependencies, and provides SBOM generation that documents your authentication infrastructure. When a vulnerability is discovered in an OAuth library you depend on, Safeguard.sh alerts you immediately.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.