1. Forgetting PKCE for Public Clients
Public clients (SPAs, mobile apps) must use PKCE—without it, authorization codes can be intercepted and replayed. Many implementations still omit this.
Fix: Always implement Authorization Code Flow with PKCE, using code_verifier
and code_challenge
per RFC 7636.
PKCE is now mandatory per OAuth 2.1 best practices. Security Boulevard
2. Storing Tokens Insecurely
Storing tokens in localStorage
or memory exposes them to XSS attacks.
Fix: Use HttpOnly, Secure, SameSite cookies or encrypted server-side storage. Never put tokens in browser-accessible client storage.
3. Not Rotating Secrets or Tokens
Refresh tokens that never expire pose a significant attack vector.
Fix: Use refresh token rotation. Each use issues a new refresh token and invalidates the old one. Many auth providers like Okta support this.
4. Relying on Default or Broad Scopes
Default scopes often over-provision privileges unnecessarily.
Fix: Define least-privilege scopes per resource and request only what's needed. Custom scopes structure like user:read
, user:edit
prevents overreach.
5. Skipping Token Revocation Logic
On logout or admin user revocation, lingering valid tokens remain a risk. Without revocation, compromised tokens stay active.
Fix: Support RFC 7009 token revocation to revoke both access and refresh tokens explicitly. Curity
6. Using Implicit or ROPC Flows
Implicit and Resource Owner Password Credentials flows are deprecated and insecure (tokens exposed in URL fragments or sent in plaintext).
Fix: Avoid these flows. Use Authorization Code + PKCE for all client types, even SPAs. DEV Community
7. Not Validating redirect_uri
or state
Strictly
Open redirect vulnerabilities and CSRF attacks arise when redirect_uri
matching or state
validation is weak or missing.
Fix: Require exact matching of registered redirect URIs and verify state
token on callback. Outpost24
8. Not Validating Token Claims (iss, aud, exp)
Accepting unsigned or expired tokens without verifying issuer, audience, and expiry opens the door for token reuse or man-in-the-middle attacks.
Fix: Always validate JWT signatures and check iss
, aud
, and exp
claims, whether via introspection or JWT verification.
9. Mixing Permissions into Tokens Directly
Embedding granular permissions in tokens couples the token schema tightly to access logic. This makes changes hard over time.
Fix: Store only role
in JWT and map it server-side to permission sets. This keeps tokens lightweight and maintainable.
10. No Audit or Logging of Token Use
Silent failures or unauthorized token use can go undetected without visibility.
Fix: Log token issuance, refresh, revocation, and failures. Track token_type
, client ID, and user for every OAuth event.
Example Code: Implementing Proper Token Rotation & Revocation
On logout:
Final Takeaway
|
By addressing each of these ten mistakes, your OAuth implementation moves from fragile and insecure to robust and maintainable. OTP isn’t inherently insecure—insecure implementations are.
NEVER MISS A THING!
Subscribe and get freshly baked articles. Join the community!
Join the newsletter to receive the latest updates in your inbox.