
PoC para CVE-2025-65945 (Verificação Impropria de Assinatura Criptográfica em node-jws)
Esta é uma prova de conceito para um bypass de verificação de assinatura na biblioteca node-jws. O bug permite que atacantes forjem JWTs válidos quando o servidor deriva segredos HMAC de dados controlados pelo usuário.
A função jws.createVerify() não valida se um segredo foi realmente fornecido ao usar algoritmos HMAC. Se seu aplicativo consulta segredos com base em algo no JWT (como um cabeçalho kid) e essa consulta falha, você pode acabar verificando contra um segredo vazio.
Um atacante pode explorar isso ao:
undefined, que é convertido para string vaziaO atacante agora pode se passar por qualquer pessoa ou conceder a si mesmo privilégios de administrador.
Atualize para 3.2.3+ ou 4.0.1+ para corrigir isso.
Certifique-se de ter o Bun instalado, então:
# Install the vulnerable version
bun install [email protected]
# Run the exploit
bun run exploit.js
Você deve ver uma saída mostrando um token de administrador forjado sendo aceito como válido.
O PoC simula um servidor que:
kid (ID da chave) do JWTcreateVerify() com a API de streamingO atacante cria um JWT com kid: "non-existent-key" e o assina com um segredo vazio. Quando o servidor tenta consultar essa chave, ele obtém undefined, escreve uma string vazia no fluxo de verificação, e o token forjado passa na validação.
# Upgrade to patched version
bun install [email protected]
# Run again - should fail now
bun run exploit.js
Com a versão corrigida, você verá um erro: secret must be a string or buffer or a KeyObject. A correção valida que operações HMAC têm um segredo adequado antes de prosseguir.
Se seu código se parece com isso, você pode estar afetado:
const decoded = jws.decode(token);
const secret = lookupSecret(decoded.header.kid); // might return undefined!
const verifier = jws.createVerify({
algorithm: "HS256",
signature: token,
});
verifier.secret.write(secret); // oops
verifier.secret.end();