> For the complete documentation index, see [llms.txt](https://ben-hurs-organization.gitbook.io/guia-de-appsec/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ben-hurs-organization.gitbook.io/guia-de-appsec/cheat-sheets/jwt.md).

# 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.

{% code title="JWT com chave assimétrica" lineNumbers="true" %}

```js
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);

```

{% endcode %}

Veja um exemplo funcional no [Replit](https://replit.com/@bhrott/JWT-RS256-Nodejs#index.js).

### 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](https://blog.pentesteracademy.com/hacking-jwt-tokens-the-none-algorithm-67c14bb15771).

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

```json
{
  "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:

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

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

## Links Úteis

* [Site Oficial - jwt.io](https://jwt.io/)
* [RFC 7519](https://www.rfc-editor.org/rfc/rfc7519)
* [tokens.dev](https://token.dev/)
* [Portswigger Academy - JWT Attacks](https://portswigger.net/web-security/jwt)
* [Auth0 - JWT](https://auth0.com/docs/secure/tokens/json-web-tokens)

## Artigos

* [How to use Azure to crack API auth tokens](https://danaepp.com/how-to-use-azure-to-crack-api-auth-tokens)
