How to Fix JWT Token Vulnerabilities in Laravel
Weak JWT implementation in your Laravel API can lead to authentication bypass and token forgery. Learn how to secure your JWT setup.
The Problem
Weak JWT (JSON Web Token) implementations allow attackers to forge authentication tokens, bypass authorization, and impersonate users. Common vulnerabilities include using weak signing algorithms (none or HS256 with weak secrets), not validating token expiration, accepting tokens with modified algorithms, and storing sensitive data in the JWT payload. These issues are especially prevalent in Laravel API applications using packages like tymon/jwt-auth.
How to Fix
-
1
Use a strong signing secret
Generate a strong JWT secret using the package command:
{{ trim($paragraph)); ?>This generates a random 64-character secret and adds it to your .env:
{{ trim($paragraph)); ?>Never use short, guessable secrets. The secret should be at least 256 bits (32 characters) for HS256. Consider using RS256 (asymmetric) for additional security:
{{ trim($paragraph)); ?> -
2
Set appropriate token expiration
Configure short-lived access tokens with refresh token rotation. In config/jwt.php:
{{ trim($paragraph)); ?>Implement refresh token rotation in your controller:
{{ trim($paragraph)); ?> -
3
Validate tokens strictly
Ensure your JWT middleware validates all required claims. In your auth guard configuration (config/auth.php):
{{ trim($paragraph)); ?>Add custom claim validation in your auth controller:
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>{{ trim($paragraph)); ?> -
4
Do not store sensitive data in JWT payload
JWT payloads are base64-encoded, not encrypted. Anyone can read them. Never include:
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>
How to Verify
Test your JWT implementation:
1. Decode a token at jwt.io and verify it does not contain sensitive data 2. Try using an expired token - it should return 401 3. Modify the payload of a valid token and send it - it should return 401 4. Send a token with alg:none in the header - it should be rejected
curl -H "Authorization: Bearer expired-or-tampered-token" https://yourdomain.com/api/user
This should return 401 Unauthorized.
Prevention
Consider using Laravel Sanctum for SPA authentication instead of JWT, as it uses session-based authentication which avoids many JWT pitfalls. If JWT is required, use well-maintained packages, rotate secrets regularly, and implement token blacklisting for logout. Monitor for unusual authentication patterns.
Frequently Asked Questions
Should I use JWT or Laravel Sanctum?
For SPAs communicating with their own backend, use Sanctum (session-based) as it avoids JWT complexity. Use JWT only when you need stateless authentication for third-party API consumers, mobile apps, or microservices that cannot share sessions. Sanctum also supports API tokens for these use cases.
What is the "none" algorithm attack?
Some JWT libraries accept tokens with the algorithm set to "none", which means no signature verification. An attacker can modify the token payload, set alg to none, remove the signature, and the server accepts it. Modern JWT packages reject alg:none by default, but always verify your configuration.
How do I handle JWT logout?
JWTs are stateless, so you cannot invalidate them server-side by default. Enable token blacklisting in your JWT package (blacklist_enabled = true), which stores invalidated token IDs in cache. On logout, add the token to the blacklist. The trade-off is that blacklisting requires server-side state, partially negating JWT's stateless benefit.
Related Guides
How to Fix Insecure Session Configuration in Laravel
Your Laravel session cookies are missing secure flags, enabling session hijacking and cross-site attacks. Fix your session config now.
How to Fix Missing Rate Limiting in Laravel
Your Laravel login and API endpoints have no rate limiting, enabling brute-force attacks and API abuse. Add throttling now.
How to Fix CORS Misconfiguration in Laravel
Wildcard CORS headers or misconfigured CORS policy allows any website to access your Laravel API. Learn how to configure CORS securely.
Detect This Automatically with StackShield
StackShield continuously monitors your Laravel application from the outside and alerts you when security issues are found. No installation required.
Start Free Trial