JWT Security Best Practices for Developers

Published on · 744 words

Want to follow along with this guide? Open the free JWT Debugger and test every pattern in real time with match highlighting and explanations.

JSON Web Tokens are powerful tools for authentication and authorization, but they come with security considerations that every developer must understand. A misconfigured JWT implementation can expose your application to token theft, replay attacks, and unauthorized access.

This guide covers the essential security best practices for JWT implementation, from choosing appropriate expiration times and secure storage mechanisms to implementing refresh token rotation and defending against common vulnerabilities like algorithm confusion attacks.

Token Expiration and Lifetimes

Every JWT should have an expiration time (exp claim). Short-lived access tokens (5-15 minutes) minimize the window of opportunity for attackers if a token is stolen. The exact duration depends on your security requirements and user experience tradeoffs.

For longer sessions, use a refresh token mechanism. Access tokens remain short-lived, while refresh tokens (stored securely server-side) are used to obtain new access tokens without requiring the user to re-authenticate. Refresh tokens should be rotated on each use — issuing a new refresh token with each access token refresh.

Never set excessively long expiration times for access tokens. A token valid for 24 hours or more significantly increases the risk window if compromised. The industry standard is 5-15 minutes for access tokens with refresh token rotation for session continuity.

Secure Token Storage

Where you store JWTs on the client side matters enormously for security. The three common options are localStorage, sessionStorage, and httpOnly cookies, each with different tradeoffs.

localStorage and sessionStorage are vulnerable to Cross-Site Scripting (XSS) attacks. If an attacker can execute JavaScript on your page, they can read tokens from storage and exfiltrate them. This is the most common JWT security mistake.

httpOnly cookies are the recommended storage mechanism for JWTs. They are not accessible via JavaScript, making them immune to XSS-based token theft. Combine them with the Secure flag (HTTPS only) and SameSite=Strict or SameSite=Lax attribute to prevent CSRF attacks. For additional CSRF protection, implement the Double Submit Cookie pattern.

Common JWT Vulnerabilities and Defenses

The 'none' algorithm attack occurs when an attacker changes the algorithm in the header to 'none', tricking the server into accepting the token without signature verification. Always validate the algorithm on the server side and reject tokens with unexpected algorithms.

Algorithm confusion attacks exploit servers that accept both symmetric (HMAC) and asymmetric (RSA) algorithms. An attacker can sign a token with the public key (which is often publicly available) using HMAC, and the server may use the public key as the HMAC secret, accepting the forged token. Fix: always specify the expected algorithm explicitly and never trust the token's algorithm header.

Token replay attacks occur when a stolen token is reused. Defenses include: short expiration times, refresh token rotation, binding tokens to client fingerprints (IP, user agent), and maintaining a token revocation list for critical scenarios.

  • Always validate the algorithm — never trust the token header
  • Use short-lived access tokens (5-15 minutes)
  • Store tokens in httpOnly cookies, not localStorage
  • Implement refresh token rotation
  • Use HTTPS exclusively
  • Validate the issuer (iss) and audience (aud) claims
  • Implement token revocation for sensitive operations

Frequently Asked Questions

Where should I store JWT tokens on the client?
Store JWTs in httpOnly cookies with Secure and SameSite attributes. This prevents XSS attacks from stealing tokens and provides CSRF protection. Avoid localStorage and sessionStorage as they are accessible to JavaScript and vulnerable to XSS.
How long should a JWT token be valid?
Access tokens should be short-lived: 5-15 minutes is the industry standard. For longer sessions, use refresh tokens that are rotated on each use. Never set access token expiration longer than 1 hour for sensitive applications.
What is the 'none' algorithm attack?
An attacker changes the JWT header algorithm to 'none', causing the server to skip signature verification. The fix is to always validate the algorithm on the server side and explicitly reject tokens with unexpected or missing algorithms.
How do I revoke a JWT token?
JWTs are stateless by design, making revocation challenging. Options include: maintaining a server-side blocklist of revoked token IDs (jti claim), using very short expiration times so stolen tokens expire quickly, or implementing refresh token rotation where revoking the refresh token effectively ends the session.
Should I use symmetric or asymmetric signing for JWT?
Symmetric (HMAC) is simpler and suitable for single-service architectures where the same service signs and verifies tokens. Asymmetric (RSA/ECDSA) is better for microservices where different services need to verify tokens without sharing a secret. Use asymmetric signing when the signing service and verification services are separate.

Try it now — free, private, and instant

Paste a JWT token to decode and inspect its header, payload, and signature instantly.

Launch the JWT Debugger