Fast Guide
Here are the main precautions when using JWT tokens:
1. Use a strong signature
When we sign our token, we need to use a sizable secret.
We can sign a JWT token in several ways, but the main ones are using symmetric (HS256, HMAC + SHA-256) and asymmetric (RS256, RSA + SHA-256) keys.
As a recommendation, it is better to use asymmetric signature, since:
- Only one service can generate the token (using private key), while other services can only verify it (public key).
- If the private key is compromised, rotating it does not break other applications with the current token, after all, the public verification keys will continue to work.
JWT with asymmetric key
const fs = require('fs');
const jwt = require('jsonwebtoken');
// use 'utf8' to get string instead of byte array (512 bit key)
const privateKEY = fs.readFileSync('./private.key', 'utf8');
const publicKEY = fs.readFileSync('./public.key', 'utf8');
const payload = {
name: 'Gandalf'
}
// SIGN
const signOptions = {
issuer: "Authorizaxtion/Resource/This server",
subject: "iam@user.me",
audience: "Client_Identity",
expiresIn: "1d",
algorithm: "RS256"
};
const token = jwt.sign(payload, privateKEY, signOptions);
console.log('\n\n=== TOKEN ===');
console.log(token);
// VERIFY
var verifyOptions = {
issuer: "Authorizaxtion/Resource/This server",
subject: "iam@user.me",
audience: "Client_Identity",
expiresIn: "1d",
algorithm: "RS256"
};
const verified = jwt.verify(token, publicKEY, verifyOptions);
console.log('\n\n=== VERIFIED ===');
console.log(verified);
// DECODE
const decoded = jwt.decode(token, { complete: true });
console.log('\n\n=== DECODED ===');
console.log(decoded);
See a functional example at Replit
2. Always define the algorithm when performing the check
There is a type of vulnerability that occurs in some JWT configurations which is the None Algorithm
In summary, the attacker changes the JWT header to:
{
"typ": "JWT",
"alg": "none"
}
And in the backend the lib we use takes the alg value and ignores the verification key.
To prevent this from happening, we must always define the alg when checking the token:
var verifyOptions = {
//...
algorithm: "RS256"
};
const verified = jwt.verify(token, publicKEY, verifyOptions);
Usefull links
Articles
Top comments (0)