O Algoritmo none: Forjando um JWT Que o Servidor Aceita Sem Assinatura
O desafio
Esta API autentica você a partir das claims dentro do seu JWT. O cabeçalho diz alg:HS256, mas o servidor tem uma falha clássica: ele também aceita um token cujo cabeçalho diz alg:none, tratando-o como já válido, sem assinatura a verificar. Na bancada, troque o algoritmo do cabeçalho para none e reescreva o payload para que role vire admin. O token se reconstrói ao vivo. Copie o token forjado inteiro e envie.
O que você vai aprender
- Entender o que o campo alg do cabeçalho JWT controla
- Explicar por que aceitar alg:none desativa a verificação de assinatura
- Forjar um token admin trocando o algoritmo para none e editando o payload
- Reconhecer a aceitação de alg:none como um bypass crítico de autenticação
- Saber que o servidor deve fixar o algoritmo esperado, em vez de confiar no cabeçalho do token
Habilidades testadas
Pré-requisitos
- Um JWT tem três partes em base64url: cabeçalho, payload e assinatura
- Claims como role e user ficam no payload
- Edição básica de JSON
Como funciona
Um JSON Web Token carrega o nome de um algoritmo em seu cabeçalho, por exemplo {"alg":"HS256","typ":"JWT"}. A intenção é que o servidor leia alg, e então verifique a assinatura com esse algoritmo e uma chave secreta. O erro fatal que algumas implementações cometem é confiar no cabeçalho controlado pelo atacante para escolher o algoritmo. Se o cabeçalho diz alg:none e a biblioteca honra isso, o servidor trata o token como legitimamente não assinado e não realiza verificação alguma.
Isso transforma o JWT em uma lista simples e editável de claims. Como nada verifica a assinatura, você pode reescrever qualquer claim que quiser. Aqui a decisão de acesso é a claim role, então você troca o cabeçalho para {"alg":"none","typ":"JWT"} e muda "role":"user" para "role":"admin". A bancada recodifica os dois segmentos e reconstrói o token. O terceiro segmento (a assinatura) deixa de importar; um token alg:none costuma ser enviado com assinatura vazia, por isso um ponto final sem nada depois também é aceito.
Essa classe de bug inteira existe porque o algoritmo deveria ser uma decisão do lado do servidor, nunca algo que quem chama pode rebaixar. Fixe-o.
Erros comuns
- Editar apenas o payload. Se você deixar o cabeçalho como HS256, a assinatura original fica inválida - esse ataque exige trocar o cabeçalho para
nonepara que o servidor pule a verificação. - Tentar calcular uma assinatura real. O ponto do
alg:noneé que você não precisa de uma; não perca tempo forjando um HMAC válido. - Mudar a claim errada. O acesso aqui é decidido por
role; defina-a comoadmin, nãouserousub. - Enviar o JSON decodificado. Envie o token reconstruído e recodificado (ou seu segmento de payload admin), não as claims legíveis por humanos.
Como se proteger
Nunca deixe que o próprio cabeçalho do token decida se ou como ele deve ser verificado. O servidor deve escolher o algoritmo e rejeitar qualquer coisa que desative a verificação.
- Fixe o algoritmo esperado no lado do servidor e rejeite
alg:none(e qualquer alg inesperado) de imediato, antes de processar as claims. - Use uma versão confiável da biblioteca e passe o algoritmo explicitamente na chamada de verificação; nunca confie no padrão da biblioteca para ler o alg a partir do token.
- Derive a autorização somente a partir de claims de um token cuja assinatura tenha sido verificada com a chave correta.
- Prefira tokens de curta duração e, para papéis sensíveis, verificações de sessão no lado do servidor, para que um único token forjado não signifique comprometimento total.