CEVIU Logo
Voltar

Como o 'Fortalecimento da Criptografia' Quebrou a Autenticação: FreshRSS e o Limite de 72 Bytes do bcrypt

Aprofundamento CEVIU

Aprofundamento

A CVE-2025-68402 não é um erro de implementação aleatória, é um caso clássico de 'fortalecimento criptográfico' mal aplicado. Trocar SHA-1 por SHA-256 no nonce parecia uma melhoria óbvia, mas ignorou uma regra fundamental do bcrypt: ele lê apenas os primeiros 72 bytes da entrada e descarta o restante sem aviso. Como o nonce passou de 40 para 64 caracteres hexadecimais (128 bytes em UTF-8), a concatenação $nonce . $hash deixou apenas 8 bytes disponíveis para o hash real da senha, o suficiente para o prefixo $2y$10$ e um pedaço do salt, mas zero bytes para os dados que dependem da senha. Resultado: password_verify() validava qualquer senha digitada.

O erro se repete em outros projetos: a Okta sofreu com CVE-2025-61884 por concatenar identificadores longos antes do hash, e o Spring Security teve CVE-2025-22228 por não tratar senhas acima de 72 caracteres como inválidas antes de chamar matches(). A lição não é trocar algoritmos, mas entender como eles lidam com entradas compostas, e testar o comportamento sob limite, não só sob condição ideal.

Por que isso importa

Empresas que usam FreshRSS em ambientes corporativos ou governamentais para agregação de feeds de segurança, inteligência de ameaças ou monitoramento regulatório poderiam ter exposto credenciais de acesso a sistemas internos, mesmo sem ter implantado a branch edge, pois alguns administradores testam versões de desenvolvimento em ambientes paralelos. Mais grave: essa falha mostra como decisões técnicas bem-intencionadas (como migrar para SHA-256) viram vetores de ataque quando feitas sem revisão de impacto em camadas inferiores, como funções de verificação de senha. Não é sobre 'criptografia forte', mas sobre composição segura de primitivas.

Perguntas frequentes

Essa vulnerabilidade afetou versões estáveis do FreshRSS?

Não. A falha existia apenas na branch de desenvolvimento (edge), nunca foi lançada em nenhuma versão estável. Usuários que mantêm instâncias com releases oficiais (ex: 1.26.x) não foram impactados.

Por que o bcrypt trunca em 72 bytes e não dá erro?

É um comportamento intencional desde a implementação original do bcrypt em C. Ele converte a entrada em um array de 18 palavras de 32 bits (72 bytes). Entradas maiores são cortadas silenciosamente, uma escolha de projeto antiga, não um bug. Muitas bibliotecas modernas ainda replicam esse comportamento por compatibilidade.

Como evitar esse tipo de erro ao usar bcrypt com dados compostos?

Duas práticas eficazes: (1) validar o comprimento total da string antes de passar para password_verify() e rejeitar entradas acima de 72 bytes; (2) usar funções de derivação de chave (como HKDF) para combinar dados antes de alimentar o bcrypt, garantindo saída fixa e controlada.

Existe risco em migrar para Argon2 ou scrypt nesse cenário?

Argon2 não tem limite rígido de 72 bytes, mas exige cuidado com parâmetros de memória e tempo. O risco real não está no algoritmo, mas na forma como os dados são preparados. Migrar sem revisar a lógica de concatenação não resolve o problema, só muda onde ele pode reaparecer.

Fontes

Avalie este artigo:
Compartilhar:
Categoria
CEVIU Segurança da Informação
Publicado
12 de março de 2026
Editoria
CEVIU Segurança da Informação

Quer receber mais sobre CEVIU Segurança da Informação?

Conteúdo curado diariamente, direto no seu e-mail.

Conteúdo curado diariamenteDiversas categoriasCancele quando quiser