Pular para o conteúdo
Todos os conceitos

Segredo HMAC fraco

Com HS256, quem sabe o segredo pode assinar qualquer token. Um segredo adivinhável entrega isso.

O algoritmo HS256 assina o token com HMAC-SHA256, usando um único segredo que o servidor guarda. Assinar e conferir usam o mesmo segredo: a assinatura é HMAC(segredo, header.payload). Quem descobre o segredo pode montar e assinar qualquer token, inclusive um com role: admin que passa em qualquer verificação.

A assinatura não tem volta, mas isso não protege um segredo fraco. Se o segredo é uma palavra comum, um ano, o nome do sistema (galpao2021), dá para testar candidatos um a um: para cada palavra de uma lista, recalcule a assinatura sobre o header.payload do token e veja qual reproduz a assinatura que veio. A que bater é o segredo.

lista de candidatos secret password galpao galpao2021 changeme ... para cada palavra: HMAC sobre header.payload HMAC-SHA256 assinatura que veio no token igual: achou o segredo assina qualquer token novo role: admin
Para cada palavra da lista, calcula-se HMAC sobre header.payload; a palavra cuja assinatura reproduz a do token é o segredo, e com ele o atacante assina um token novo.

Em Python, o laço é curto:

import hmac, hashlib, base64
signing_input = (header_b64 + "." + payload_b64).encode()
for w in open("wordlist.txt").read().split():
    sig = base64.urlsafe_b64encode(
        hmac.new(w.encode(), signing_input, hashlib.sha256).digest()
    ).rstrip(b"=").decode()
    if sig == token_signature:
        print("secret:", w)

O conserto é um segredo longo e aleatório (32 bytes ou mais, de um gerador seguro), guardado fora do código, em variável de ambiente ou cofre. Aí nenhuma lista de palavras chega perto.

Aparece nestes desafios