JWT

Guia Rápido

Aqui vão os principais cuidados ao utilizar tokens JWT:

1. Utilizar uma assinatura forte

Quando assinamos o nosso token, precisamos utilizar um segredo de tamanho considerável.

Podemos assinar um token JWT de várias formas, mas as principais são utilizando chaves simétricas (HS256, HMAC + SHA-256) e assimétricas (RS256, RSA + SHA-256).

Como recomendação, é melhor utilizar assinatura assimétrica, uma vez que:

  • Apenas um serviço consegue gerar o token (utilizando chave privada), enquanto outros serviços só conseguem verificar (chave pública).

  • Se a chave privada for comprometida, rotacionar ela não quebra as outras aplicações com o token atual, afinal, as chaves públicas de verificação continuarão funcionando.

JWT com chave assimétrica
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);

Veja um exemplo funcional no Replit.

2. Sempre definir o algorítmo no momento de fazer a verificação

Existe um tipo de vulnerabilidade que ocorre em algumas configurações de JWT que é o None Algorithm.

Em resumo, o atacante muda o header do JWT para:

{
  "typ": "JWT",
  "alg": "none"
}

E no backend a lib que usamos pega o valor do alg e ignora a chave de verificação.

Para que isto não aconteça, sempre devemos definir o alg no momento de verificar o token:

var verifyOptions = {
  //...
  algorithm: "RS256"
};

const verified = jwt.verify(token, publicKEY, verifyOptions);

Artigos

Last updated