JSON Web Tokens (JWT) are widely used in Laravel applications for authentication and authorization. However, improper implementation can expose your application to serious security vulnerabilities. In this guide, we’ll explore different JWT attacks, how they are exploited, and how you can secure your Laravel application against them.
JWT (JSON Web Token) is a compact, self-contained way of securely transmitting information between parties as a JSON object. It consists of three parts:
Header – Contains metadata about the token (e.g., algorithm used).
Payload – Contains claims (user information, expiry time, etc.).
Signature – Ensures token integrity and authenticity.
A typical JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJpYXQiOjE2ODMwMDAwMDAsImV4cCI6MTY4MzAwMzYwMH0.qeQWxKwTt4FLd5P7-QBeDl5zQsXFTTHk06V6JZzRczk
When a Laravel app uses JWT for authentication, the token is included in the request headers and verified by the backend. If JWT security is misconfigured, attackers can exploit vulnerabilities to hijack sessions, forge tokens, or bypass authentication.
1. None Algorithm Attack (Algorithm Confusion Attack)
If a JWT is incorrectly implemented, attackers can modify the header to specify "alg": "none", bypassing signature validation.
Vulnerable Code:
use Firebase\JWT\JWT;
$token = $_GET['token'];
$decoded = JWT::decode($token, $secretKey, array('none')); // Accepts unsigned tokens
echo "User ID: " . $decoded->user_id;
Fix: Always validate the signature with a strong algorithm like HS256 or RS256.
use Firebase\JWT\JWT;
$token = $_GET['token'];
$decoded = JWT::decode($token, $secretKey, array('HS256')); // Enforces signature validation
echo "User ID: " . $decoded->user_id;
2. Weak Secret Key Attack
If the secret key used to sign JWTs is weak, attackers can brute-force it and forge valid tokens.
Vulnerable Code:
$secretKey = "12345"; // Weak key
$jwt = JWT::encode($payload, $secretKey, 'HS256');
Fix: Use a strong, randomly generated key.
$secretKey = bin2hex(random_bytes(32)); // Strong key
$jwt = JWT::encode($payload, $secretKey, 'HS256');
3. Expired Token Replay Attack
A stolen JWT can be reused if it's not invalidated after logout.
Fix: Implement a token blacklist mechanism in Laravel.
if (TokenBlacklist::isBlacklisted($token)) {
die("Invalid token.");
}
4. JWT Injection via Unvalidated Input
If JWTs are directly accepted from user input without validation, attackers can inject malicious payloads.
Vulnerable Code:
$token = $_GET['token'];
$decoded = JWT::decode($token, $secretKey, ['HS256']); // No validation
Fix: Always validate input before decoding JWT.
if (!preg_match('/^[A-Za-z0-9\-\._]+$/', $_GET['token'])) {
die("Invalid token format.");
}
$decoded = JWT::decode($token, $secretKey, ['HS256']);
Avoid none algorithm.
Prefer RS256 over HS256 for better security.
$privateKey = file_get_contents('/path/to/private.key');
$jwt = JWT::encode($payload, $privateKey, 'RS256');
Short-lived tokens reduce the impact of token theft.
$payload = [
"user_id" => 1,
"iat" => time(),
"exp" => time() + 3600 // 1-hour expiry
];
$jwt = JWT::encode($payload, $secretKey, 'HS256');
Use refresh tokens to generate new JWTs securely.
DO NOT store JWTs in localStorage (prone to XSS).
Use httpOnly and Secure cookies.
setcookie("jwt", $jwt, [
"httponly" => true,
"secure" => true
]);
Blacklist old tokens after logout to prevent reuse.
TokenBlacklist::add($token);
Create a middleware to verify JWTs before processing requests.
namespace App\Http\Middleware;
use Closure;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class AuthenticateJWT {
public function handle($request, Closure $next) {
$token = $request->header('Authorization');
if (!$token) {
return response()->json(['error' => 'Unauthorized'], 401);
}
try {
$decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS256'));
$request->user = $decoded;
} catch (\Exception $e) {
return response()->json(['error' => 'Invalid token'], 401);
}
return $next($request);
}
}
To ensure your Laravel application is secure, use our free Website Security Scanner.
Image 1: Screenshot of our free Website Security Checker tool
Screenshot of the free tools webpage where you can access security assessment tools.
After scanning, you will receive a detailed website vulnerability assessment report to check Website Vulnerability, which helps identify security flaws in your application.
Image 2: Screenshot of a vulnerability assessment report generated by our tool
An Example of a vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.
Securing JWT authentication in Laravel is crucial to prevent token forgery, replay attacks, and unauthorized access. By implementing strong signing algorithms, enforcing short-lived tokens, validating input, and using secure storage, you can greatly enhance your application's security.
For more cybersecurity tips, visit Pentest Testing Corp blog.
Have questions or need a security assessment? Try our website security checker today! 🚀