DEV Community

Iannetta
Iannetta

Posted on

JWT

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);
Enter fullscreen mode Exit fullscreen mode


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"
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

Usefull links


Articles

Top comments (0)