Glossário
O que é um JWT (JSON Web Token)? Como funciona o passe assinado e como usá-lo com segurança
Um JWT (JSON Web Token) é um 'passe' à prova de adulteração que um servidor assina. Como funcionam header/payload/signature e os perigos: pular a verificação da assinatura, permitir alg:none e colocar segredos no payload.
"O passe assinado que um servidor te entrega depois do login" — isso é um JWT. Veja como ele funciona e os pontos-chave para usá-lo com segurança (sem passos de ataque).
Como funciona (três partes)
Um JWT é header.payload.signature unidos por .. O header e o payload são apenas codificados em base64url (não criptografados); só a assinatura é feita com uma chave secreta (ou compartilhada).
1. header
metadados como o algoritmo de assinatura. qualquer um pode ler
2. payload
claims como id do usuário e expiração. qualquer um pode ler = sem segredos
3. signature
feita com uma chave. garante a ausência de adulteração
O ponto-chave é que o conteúdo é "apenas legível". Então o payload não é lugar para senhas ou dados pessoais. O valor de um JWT é que, ao verificar a assinatura, o servidor pode confirmar "eu emiti este token e ele não foi alterado".
Defesas para usá-lo com segurança
Sempre verifique a assinatura e fixe o alg (o mais importante)
Verifique a assinatura no servidor toda vez. Fixe o algoritmo de assinatura (alg) aceito no valor que você espera e rejeite alg:none (sem assinatura). Não confie cegamente no alg escrito no header do token.
Não coloque segredos no payload
Suponha que qualquer pessoa pode decodificar o conteúdo. Mantenha segredos — senhas, dados pessoais, chaves de API — fora dele. Inclua apenas claims que não sejam catastróficos se vistos, como identificadores e permissões.
Mantenha a expiração curta e tenha como revogar
Faça os tokens de acesso de curta duração. Uma expiração longa demais estende a janela de dano se um for roubado. Se você precisa de revogação, paree um token de acesso de curta duração com um refresh/sessão gerenciado pelo servidor.
Use uma chave forte e armazene-a onde não possa ser roubada
Faça a chave de assinatura forte, não a reutilize e armazene-a em algum lugar seguro no servidor. Proteja também o próprio token — evite que seja roubado via XSS, carregue-o num cookie com atributos seguros (→ cuidado com o roubo via XSS).
A visão deste site: um JWT não é uma sessão de propósito geral
Os JWTs são muitas vezes usados para "manter o estado de login", mas têm uma fraqueza: a revogação é difícil. Se a assinatura é válida e não expirou, o servidor basicamente confia nela, então fazer um logout ou uma invalidação ter efeito imediato é complicado. Nossa postura é: não faça de um JWT uma sessão de propósito geral de longa duração. Combine um token de acesso de curta duração com um refresh/sessão revogável no servidor, e você obtém tanto a vantagem do JWT (verificação barata) quanto a revogação fácil. Escolha o uso certo para ele.
Ponto cego: "decodificou" não é "é válido"
Como o conteúdo é legível, qualquer pessoa pode colar um JWT num decodificador de JWT e inspecionar o header e o payload. Mas decodificar (ler o conteúdo) e verificar (confirmar a autenticidade) são coisas inteiramente diferentes. Conseguir decodificar não garante nada sobre a validade. O que decide se um token é genuíno é sempre a verificação da assinatura no servidor. Ler o conteúdo para depuração é prático — apenas não confunda "consegui ler" com "é válido".
Leia a seguir
- Ferramenta: Decodificador / inspetor de JWT (verifique o conteúdo, detecte alg:none ou expiração)
- Glossário: o que é XSS (uma rota clássica de roubo de token) / o que é CSRF
- Aprenda: escolhendo o MFA do jeito certo
FAQ
QO conteúdo de um JWT é criptografado?
Não. O header e o payload de um JWT padrão são 'codificados' com base64url, não criptografados, então qualquer pessoa que tenha o token pode ler o conteúdo. Por isso, nunca coloque segredos como senhas ou dados pessoais no payload. O que um JWT protege não é a 'confidencialidade do conteúdo', mas o fato de que 'ele não foi adulterado' (integridade, via a assinatura).
QQual é a configuração mais perigosa de um JWT?
Não verificar a assinatura, ou aceitar 'alg:none' (sem assinatura). Permitir isso deixa um atacante passar um token forjado com conteúdo livremente reescrito. A defesa é sempre verificar a assinatura no servidor e fixar o algoritmo de assinatura (alg) aceito no valor que você espera.
QDecodificar e verificar são a mesma coisa?
Não. Decodificar apenas lê o conteúdo e qualquer pessoa pode fazê-lo (você pode checar com um decodificador de JWT). Verificar é o servidor confirmar, com uma chave secreta/pública, que a assinatura é válida, que o token não expirou e que o emissor/público estão corretos. 'Decodificou' não significa 'é um token válido' — a verificação no servidor decide a autenticidade.