Skip to content
Back to Blog
jwtsecurityvulnerabilityauthentication

Ataques JWT alg:none e Confusão de Algoritmos Explicados

Dois ataques clássicos JWT, alg:none e confusão RS256-para-HS256, exploram servidores que confiam no cabeçalho alg. Explicamos cada ataque passo a passo e a correção simples com lista de permissões.

SZ
Founder, Molixa
11 min read
Compartilhar
Ataques JWT alg:none e Confusão de Algoritmos Explicados
Table of contents6 sections

A vulnerabilidade do algoritmo jwt none permite que um invasor remova a assinatura de um token e reescreva seu conteúdo, e o servidor aceita o token falsificado como válido. Isso acontece quando seu código confia no campo alg dentro do cabeçalho do token em vez de decidir o algoritmo por conta própria. A mesma causa raiz alimenta o ataque de confusão RS256 para HS256. Ambos são bypasses de autenticação, e ambos são resolvidos com uma linha de código.

Se você utiliza JSON Web Tokens, este é um dos poucos bugs de segurança que transforma um incômodo de leitura em uma tomada total de conta. Um invasor que consegue forjar um token válido pode definir "sub": "admin", não assinar nada e entrar. Abaixo você verá exatamente como cada ataque funciona, com os bytes detalhados, além da correção com lista de permissões que elimina toda essa classe de bug.

O Que a Vulnerabilidade do Algoritmo Nenhum (None) em JWTs Realmente É#

Um JWT tem três partes separadas por pontos: um cabeçalho base64url, um payload base64url e uma assinatura. O cabeçalho declara qual algoritmo assinou o token, como {"alg":"HS256","typ":"JWT"}. A assinatura é o que prova que o token não foi adulterado.

O algoritmo none é uma parte legítima da especificação JWT (RFC 7519). Ele significa que o token não é assinado. Existe para situações em que a camada de transporte já garante a integridade, então a assinatura é intencionalmente vazia. O problema não é que none exista. O problema é quando uma biblioteca de verificação trata o cabeçalho alg: none do próprio token como permissão para pular completamente a verificação da assinatura.

A falha central em ambos os ataques abaixo é idêntica: o servidor lê o cabeçalho alg controlado pelo atacante e confia nele para decidir como (ou se) verificar a assinatura. Nunca deixe uma entrada não confiável escolher seu algoritmo de verificação.

A falsificação em três etapas#

Aqui está o ataque contra um servidor que honra alg: none. Digamos que um token real decodifique para este payload:

{ "sub": "1234", "role": "user", "exp": 1735689600 }

Um atacante faz três coisas:

  1. Altera o cabeçalho para {"alg":"none","typ":"JWT"} e o codifica em base64url.
  2. Edita o payload para {"sub":"1","role":"admin","exp":9999999999} e o codifica.
  3. Remove a assinatura, deixando o token terminando com um ponto final sem nada depois.

O token falsificado se parece com eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxIiwicm9sZSI6ImFkbWluIn0. (observe o ponto solto). Um servidor vulnerável decodifica o cabeçalho, vê none, pula a verificação e concede acesso de administrador. Nenhum segredo, nenhuma chave, nenhuma quebra. Você pode colar qualquer token em nosso decodificador JWT gratuito para ver exatamente qual cabeçalho alg ele carrega antes de confiar nele.

Por que "none" às vezes tem um N maiúsculo#

Algumas bibliotecas antigas bloqueavam a string none com distinção entre maiúsculas e minúsculas, mas não None, NONE ou nOnE. Como a especificação JWT trata nomes de algoritmos com distinção entre maiúsculas e minúsculas, mas o código real nem sempre fazia isso, atacantes contornavam listas de bloqueio ingênuas variando a capitalização. Esta é a primeira lição de segurança JWT: uma lista de bloqueio de valores ruins é frágil. Uma lista de permissões de valores bons não é.

O Ataque de Confusão de Algoritmo RS256 para HS256#

O ataque de confusão é mais sorrateiro e ainda pega equipes em 2026. Ele explora a diferença entre assinatura simétrica e assimétrica quando uma única chamada de verificação aceita ambas.

Duas famílias de algoritmos são relevantes aqui:

  • HS256 é simétrico. Um único segredo compartilhado assina e verifica. Quem possui o segredo pode criar tokens válidos.
  • RS256 é assimétrico. Uma chave privada assina e uma chave pública verifica. A chave pública é, por definição, pública. Não há problema em publicá-la.

Um servidor que usa RS256 mantém sua chave privada protegida e verifica os tokens recebidos com a chave pública. Isso é seguro, desde que o servidor execute apenas a verificação RS256.

Como a chave pública se torna um segredo para falsificação#

A confusão acontece quando o código de verificação se parece com isso:

// VULNERÁVEL: algoritmo obtido do cabeçalho do token
jwt.verify(token, key);

Muitas bibliotecas, ao receber um token, leem o cabeçalho alg para escolher o caminho de verificação. Se o sistema original usa RS256, o invasor faz o seguinte:

  1. Obtém a chave pública RSA. Ela geralmente está exposta em um endpoint JWKS, em uma URL .well-known, em um SDK ou simplesmente publicada na documentação.
  2. Forja um token com o cabeçalho alterado para {"alg":"HS256"} e um payload elevado.
  3. Assina esse token com HMAC-SHA256, usando os bytes exatos da chave pública como segredo HMAC.

Agora o servidor recebe um token HS256. Ele pega sua chave RSA (que acreditava ser apenas uma chave de verificação) e executa HMAC com ela. Como o invasor assinou com a mesma string da chave pública, o HMAC corresponde. A assinatura é verificada. O token de administrador falsificado é aceito.

O invasor transformou sua chave pública inofensiva e publicada no segredo que forja tokens. Ele nunca precisou da chave privada.

Aviso: a parte mais complicada de reproduzir isso é obter a representação exata em bytes da chave pública (PEM com a quebra de linha final, cabeçalhos incluídos ou removidos). Os invasores testam por força bruta o pequeno número de codificações comuns. Considere qualquer implantação RS256 que também aceite HS256 como já comprometida.

Por que isso é tão fácil de ser enviado acidentalmente#

A vulnerabilidade quase nunca é escrita intencionalmente. Ela entra quando:

  • Uma biblioteca assume como padrão inferir o algoritmo a partir do cabeçalho do token.
  • Uma equipe migra de HS256 para RS256, mas mantém o caminho de verificação antigo ativo "por precaução."
  • Uma função wrapper aceita um argumento genérico key e o passa para qualquer algoritmo que o token solicitar.

Se você quiser entender melhor por que decodificar um token não é o mesmo que verificá-lo, a análise em decodificar versus verificar na segurança JWT mostra onde as equipes confundem os dois e abrem exatamente essa brecha.

A Correção: Coloque seu Algoritmo na Lista de Permissões#

Ambos os ataques morrem no momento em que o servidor para de confiar no cabeçalho alg do token e fixa o algoritmo que aceitará. Esta é a defesa JWT mais importante e geralmente é uma linha.

Fixe o algoritmo explicitamente#

No Node com a biblioteca comum jsonwebtoken, passe uma lista de permissões explícita de algorithms:

// SEGURO: apenas HS256 é aceito
jwt.verify(token, secret, { algorithms: ["HS256"] });

// SEGURO: apenas RS256, com a chave PÚBLICA, nada mais
jwt.verify(token, publicKey, { algorithms: ["RS256"] });

Com essa lista de permissões, um token forjado com alg: none é rejeitado porque none não está na lista. Um token HS256 forjado enviado ao verificador RS256 é rejeitado porque o verificador só executará RS256, e bytes HMAC não podem satisfazer uma verificação de assinatura RSA.

Toda biblioteca JWT madura tem o mesmo controle com um nome ligeiramente diferente:

Linguagem / BibliotecaO parâmetro da lista de permissões
Node jsonwebtokenalgorithms: ["RS256"] em verify()
Python PyJWTalgorithms=["RS256"] em jwt.decode()
Go golang-jwtWithValidMethods([]string{"RS256"})
Java java-jwt (Auth0)construir o verificador com o Algorithm específico
PHP firebase/php-jwtpassar o algoritmo para JWT::decode()

Uma pequena lista de verificação de endurecimento#

Fixar o algoritmo é a correção principal. Esses hábitos fecham o resto das lacunas:

  • Nunca aceite none em produção. Não há razão para um token de usuário logado não ser assinado.
  • Use um algoritmo por serviço. Se você não precisa de HS256 e RS256, não deixe seu verificador aceitar ambos. Misturá-los é o que convida o ataque de confusão.
  • Mantenha as chaves de verificação tipadas. Carregue sua chave pública RSA como um objeto de chave, não como uma string bruta, para que não possa ser usada acidentalmente como um segredo HMAC.
  • Valide as claims, não apenas a assinatura. Verifique exp, iss e aud. Uma assinatura válida em um token destinado a outro serviço ainda é um problema.
  • Inspecione os tokens que você recebe. Antes de integrar um token de terceiros, decodifique-o e confirme se o cabeçalho e as claims correspondem ao que você espera.

Você pode confirmar tudo isso com um token real em segundos. Nosso decodificador JWT e ferramenta de segurança mostra o cabeçalho, a carga útil e qual algoritmo o token alega, para que você possa identificar um alg: none ou um HS256 inesperado antes que ele chegue ao seu verificador. O guia complementar sobre leitura da saída do decodificador JWT para segurança de tokens explica o que cada campo lhe diz.

Como Saber se Seu Aplicativo Está Vulnerável#

Você não precisa de uma equipe de pentest para descobrir. Três verificações rápidas cobrem a maior parte da exposição real.

Verificação 1: O algoritmo está fixado?#

Pesquise em seu código todas as chamadas que verificam um token. Se algum caminho de verificação omitir uma lista de permissões de algorithms (ou seu equivalente), esse caminho confia no cabeçalho do token e é suspeito. Esta é a verificação de maior valor e leva minutos.

Verificação 2: Um token none passa?#

Pegue um token válido, altere seu cabeçalho para {"alg":"none","typ":"JWT"}, mude uma declaração, remova a assinatura (mantenha o ponto final) e envie para um endpoint protegido. Uma resposta 200 com a identidade falsificada confirma a vulnerabilidade. Um 401 confirma que o caminho a rejeita.

Verificação 3: Sua chave pública é realmente pública e algo aceita HS256?#

Se você assina com RS256, assuma que a chave pública está nas mãos de um invasor. A única coisa entre isso e um token falsificado é se algum verificador em sua pilha executará HS256. Se a resposta for sim em algum lugar, você está exposto ao ataque de confusão até fixar RS256.

Perguntas Frequentes#

A vulnerabilidade do algoritmo JWT none ainda é relevante em 2026? Sim. Bibliotecas modernas e mantidas rejeitam alg: none por padrão e exigem uma lista de permissões explícita, então uma instalação nova geralmente é segura. O bug persiste em versões antigas de bibliotecas, em código JWT feito manualmente e em aplicativos que substituem os padrões para "suportar flexibilidade". Auditar suas chamadas de verificação ainda vale a pena.

Por que publicar minha chave pública RS256 é seguro se ela pode forjar tokens? A chave pública sozinha é inofensiva. Ela só se torna perigosa quando seu servidor está disposto a executar a verificação HS256 e trata essa chave pública como um segredo HMAC. Corrija a disposição de aceitar HS256 (fixe RS256), e publicar a chave pública é exatamente tão seguro quanto o design pretende.

O que significa "lista de permissões do algoritmo" na prática? Significa informar à sua função de verificação o algoritmo ou algoritmos exatos que você aceita, em vez de deixá-la ler o algoritmo do token recebido. No jsonwebtoken, isso é verify(token, key, { algorithms: ["RS256"] }). O verificador então ignora o cabeçalho alg do token ao decidir como verificar a assinatura.

Posso apenas bloquear a string "none" para ficar seguro? Não. Listas de bloqueio são frágeis. Atacantes contornam bloqueios sensíveis a maiúsculas com None ou NONE, e uma lista de bloqueio não faz nada contra o ataque de confusão RS256 para HS256, que usa um valor HS256 perfeitamente normal. Uma lista de permissões de algoritmos aceitos defende contra ambos os ataques de uma vez.

Como inspeciono qual algoritmo um token está usando? Decodifique o primeiro segmento do token, que é o cabeçalho codificado em base64url contendo o campo alg. Você pode fazer isso manualmente ou colar o token em um decodificador JWT que mostra o cabeçalho, payload e algoritmo declarado. A decodificação nunca valida a assinatura, então trate o resultado como informativo até que seu servidor o verifique com um algoritmo fixo.

Usar um segredo mais longo ou chave mais forte corrige isso? Não. Uma chave RSA de 4.096 bits não ajuda se o verificador pode ser enganado para o modo HMAC, e um segredo HMAC forte não ajuda se o servidor aceita tokens none não assinados. Esses ataques contornam a criptografia em vez de quebrá-la, então a solução é fixar o algoritmo, não aumentar a força da chave.

A Conclusão sobre a Vulnerabilidade do Algoritmo None no JWT#

A vulnerabilidade do algoritmo none no JWT e o ataque de confusão RS256-para-HS256 compartilham uma causa raiz: confiar em entradas controladas pelo atacante para decidir como um token é verificado. Remova uma assinatura ou troque uma chave pública como segredo HMAC, e um servidor que segue as instruções do cabeçalho alg aceitará a falsificação.

Fixe o algoritmo com uma lista de permissões explícita, recuse none em produção e mantenha um algoritmo por serviço. Esse punhado de hábitos elimina toda a classe de bugs. Quando precisar confirmar o que um token realmente contém, decodifique-o primeiro e verifique-o depois com um algoritmo fixo, e você fecha a porta para sempre.

jwtsecurityvulnerabilityauthentication

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools