Autenticação JWT - Boas práticas


 Hoje vamos apresentar algumas boas práticas relacionadas com o uso do token JWT .

A sigla JWT, significa JSON Web Token, é um padrão aberto usado para compartilhar informações de segurança entre duas partes — um cliente e um servidor. Cada JWT contém objetos JSON codificados, incluindo um conjunto de declarações.

Os JWTs são assinados usando um algoritmo criptográfico para garantir que as declarações não possam ser alteradas após a emissão do token.

O JWT é uma estrutura JSON e as especificações sobre como criptografar ou assinar digitalmente um JWT é  conhecida como Javascript Object Signing & Encription (JOSE) que é composto pelos seguintes itens e suas respectivas RFC's :

Acrônimo Nomenclatura Detalhes
JWS Json Web Signature (RFC7515) Processo sobre como assinar digitalmente um JWT
JWE Json Web Encryption (RFC7516) Processo sobre como criptografar um JWT
JWK Json Web Key (RFC7517) Define uma estrutura JSON para representar uma chave de criptografia.
JWA Json Web Algorithm (RFC7518) Define os algoritmos válidos para assinar digitalmente ou criptografar um JWT

Quando um servidor recebe um JWT, ele pode garantir que os dados contidos nele sejam confiáveis porque são assinados pela fonte e assim nenhum intermediário pode modificar um JWT depois de enviado.

É importante destacar que um JWT garante a propriedade dos dados, mas não a criptografia. Os dados JSON que você armazena em um JWT podem ser vistos por qualquer pessoa que intercepte o token porque ele é apenas serializado, não criptografado.

Por esse motivo, é altamente recomendável usar HTTPS com JWTs.

Quando usar JWT

Os JWTs são usados como uma forma segura de autenticar usuários e compartilhar informações. Uma chave privada ou secreta é usada pelo emissor para assinar o JWT. O destinatário do JWT verificará a assinatura para garantir que o token não tenha sido alterado após ter sido assinado pelo emissor.

Os JWTs podem ser usados como um mecanismo de autenticação que não requer um banco de dados. O servidor pode evitar o uso de um banco de dados porque o armazenamento de dados no JWT enviado ao cliente é seguro.

O uso de JWT é particularmente útil para a autenticação de APIs e para a autorização servidor para servidor.

Quando não usar JWT

1- Como tokens revogáveis

O JWT não requer nenhuma pesquisa no banco de dados, portanto, revogá-los antes da expiração é bastante difícil.

A revogação é muito importante em muitos casos. Por exemplo, ao desconectar usuários ou banir usuários, ou alterar permissões ou senhas instantaneamente, se o token não tiver sido revogado, é possível que o usuário continue a fazer solicitações mesmo que esse usuário não tenha mais a autorização necessária para faça isso.

2- Com informação sensível

O JWT geralmente é assinado para proteger contra manipulação ou alteração de dados. Com isso, os dados podem ser facilmente lidos ou decodificados.

Portanto, você não pode incluir informações confidenciais, como o registro do usuário ou qualquer identificador, porque os dados não são criptografados.

3- O fator tamanho do cookie

O tamanho de um JWT é maior que o tamanho de um token de sessão. E isso pode aumentar rapidamente linearmente à medida que você adiciona mais dados ao JWT. E como você precisa enviar o JWT a cada solicitação, está aumentando o tamanho da carga útil.

Isso pode se tornar muito complexo se houver uma conexão de internet de baixa velocidade.

JWT - Boas práticas

1- Usar JWT como token de acesso

O JWT pode ser usado como um token de acesso para impedir o acesso indesejado a um recurso protegido. Eles são freqüentemente usados como tokens de portador ou bearer token, que a API decodificará e validará antes de enviar uma resposta.

2-  Usar JWT como token de atualização

Como você obtém um novo token de acesso se este estiver expirado? A primeira ideia natural é fazer login novamente. Mas do ponto de vista da experiência do usuário, isso pode ser bastante doloroso.

O JWT pode ser usado como tokens de atualização; esses tokens são usados para recuperar um novo token de acesso.

Por exemplo, quando um cliente solicita um recurso protegido e recebe um erro, o que pode significar que o token de acesso expirou, o cliente pode receber um novo token de acesso enviando uma solicitação com um token de atualização nos cabeçalhos ou body do request. Se o token de atualização for válido, um novo token de acesso será criado e enviado como resposta.

Observe que o token de atualização é obtido na autenticação e tem uma vida útil maior que o token de acesso.

3- Qual algoritmo usar para assinar o token ?

O JWT pode ser assinado usando muitos algoritmos diferentes. Mas vamos falar sobre o valor alg no cabeçalho JWT. Quando é decodificado:

O valor alg nos cabeçalhos JWT simplesmente informa como o JWT foi assinado. Por exemplo, com um valor alg de RS512 temos :

RS512 => RS 512 onde RS é o algoritmo de assinatura e SHA-512 é o algoritmo de hash.

O SHA-512 produzirá um hash de 512 bits, enquanto o SHA-256 produzirá um hash de 256 bits. E cada um desses algoritmos fornece 50% do tamanho de saída do nível de segurança. Isso significa que, por exemplo, o SHA-512 fornecerá segurança de 256 bits.

Em qualquer caso, certifique-se de usar um mínimo de segurança de 128 bits.

Nota:  Você pode usar o componente Jwks.Manager para gerar o JWK e fazer a sua gestão.

4- Chave simétrica ou assimétrica ?

Ao usar um algoritmo simétrico, uma única chave é usada. Tanto para criptografar os dados quanto na descriptografia. Nesse caso, as duas partes envolvidas numa comunicação precisam ter a chave. Seja para leitura, ou para escrever uma nova.

O uso da chave simétrica é indicado apenas em cenários onde haverá UMA única API. Pois, as demais API's não irão ter habilidade para validar o JWS (Json Web Signature), a menos que a chave privada seja compartilhada entre as API's.

Neste caso o algoritmo usado pode ser da família HMAC - Hash-Based Message Authentication Codes (HMACs) onde sua segurança esta ligada a função de hash usada. Ex: SHA256.

5- Expiração, Hora de Emissão e Clock Skew

Os JWTs são difíceis de revogar quando são criados. Na maioria das vezes, você terá que esperar até o vencimento. É por isso que você deve usar um tempo de expiração curto.

Além disso, você pode implementar seu próprio sistema de revogação.

O JWT vem com uma reivindicação baseada em tempo iat — emitida em. Ele pode ser usado para rejeitar tokens muito antigos para serem usados pelo servidor de recursos. E a inclinação do relógio - Clock Skew -  especifica a diferença de tempo permitida (em segundos) entre os relógios do servidor e do cliente ao verificar as declarações baseadas em tempo exp e nbf. O valor padrão recomendado é 5.

6- Assinatura JWT

A última parte de um JWT é a assinatura, que é simplesmente um MAC (ou Message Authentication Code). Essa assinatura é criada pelo servidor usando uma chave secreta. Essa chave secreta é uma parte importante da assinatura JWT.

Há duas coisas a serem respeitadas para diminuir a probabilidade de vazamento de uma chave secreta ou de um ataque de força bruta bem-sucedido:

- Manter a chave secreta em segredo;
- O comprimento mínimo da chave deve ser igual ao tamanho dos bits da função hash usada junto com o algoritmo HMAC;

7 - Onde armazenar os tokens ?

As maneiras mais fáceis de armazenar um token no lado do cliente são localStorage e sessionStorage. No entanto, ambos são vulneráveis a ataques XSS e o sessionStorage é limpo se o navegador for fechado.

Uma maneira melhor e segura é armazenar JWT em cookies, desde que você adote os seguintes procedimentos de segurança:

- Impedir Cross Site Scripting com o atributo HttpOnly;
- Proteger os cookies durante o transporte com o atributo Secure;
- Evitar falsificação de solicitação entre sites (Cross-Site Forgery) com o atributo SameSite;

Dessa forma os cookies estarão bem protegidos e, são enviados automaticamente para o servidor.

8- Sempre usar HTTPS

Um dos principais benefícios do HTTPS é que ele vem com segurança e confiança. O caminho HTTP e os parâmetros de consulta são criptografados ao usar HTTPS.

Assim, não há risco de alguém interceptar a solicitação, principalmente o token em trânsito. Esses tipos de ataques são comumente chamados de ataques MitM (man in the middle) que podem ser bem-sucedidos em redes comprometidas ou inseguras.

Assim sempre use HTTPS.

9- O que fazer quando o JWT for hackeado

O JWT é um padrão muito popular que você pode usar para confiar em solicitações usando assinaturas e trocar informações entre as partes. Certifique-se de saber quando é melhor usar, quando é melhor usar outra coisa e como evitar os problemas de segurança mais básicos.

E estamos conversados....

"Bem-aventurados os que guardam os seus testemunhos, e que o buscam com todo o coração"
Salmos 119:2

Referências:


José Carlos Macoratti