
Enumeração de Usuários via Canal Lateral de Temporização na Autenticação do PaperCut NG
| Campo | Detalhes |
|---|---|
| ID da CVE | CVE-2026-8794 |
| Produto | PaperCut NG |
| Versão Afetada | 25.0.11 (Build 75758) e anteriores |
| CWE | CWE-208 — Discrepância de Temporização Observável |
| Pontuação CVSS | 3.7 (Baixa) — isolada; escala quando encadeada com a CVE-2026-8793 |
| Pesquisador | Vivien LEBAS (@Hazaz) |
| Relatado | Maio de 2026 |
| Status | Corrigido — PaperCut NG 26.0.3 |
O endpoint de autenticação do PaperCut NG apresenta uma discrepância de temporização mensurável entre tentativas de login em contas existentes e inexistentes. Essa discrepância — causada pelo fato de o hash de senha bcrypt ser executado apenas quando uma conta correspondente é encontrada — permite que um atacante não autenticado determine de forma confiável se um determinado nome de usuário existe no sistema, medindo os tempos de resposta HTTP.
Quando combinada com a CVE-2026-8793 (ausência de proteção contra força bruta), essa vulnerabilidade possibilita uma cadeia completa de ataque de comprometimento de credenciais: primeiro enumerar nomes de usuário válidos e depois realizar tentativas ilimitadas e direcionadas de senha, sem risco de bloqueio.
A discrepância de temporização decorre de um padrão clássico de implementação: a aplicação só invoca a comparação bcrypt quando encontra no banco de dados uma conta correspondente ao nome de usuário informado. Para contas inexistentes, a rotina de autenticação sai antecipadamente — antes que o bcrypt seja chamado — resultando em um tempo de resposta mensuravelmente menor.
Valid username: DB lookup (found) → bcrypt comparison → failure response ~2.1s avg
Invalid username: DB lookup (not found) → immediate failure response ~0.2s avg
Esse padrão é bem documentado (ver CWE-208). A correção padrão é realizar uma comparação bcrypt fictícia mesmo quando a conta não existe, equalizando os tempos de resposta nos dois caminhos de código.
Tentativas de autenticação foram feitas contra o endpoint de login do PaperCut NG sob condições controladas:
curl com --write-out "%{time_total}", senha intencionalmente incorreta em todos os casosAs duas distribuições apresentam sobreposição zero, tornando a enumeração confiável mesmo com instabilidade moderada de rede.
# Measure response time for an existing account (wrong password)
curl -s -o /dev/null -w "%{time_total}\n" \
-X POST "http://<target>:9191/app" \
-H "Origin: http://<target>:9191" \
--data "service=direct/1/Home/%24Form&inputUsername=admin&inputPassword=wrongpassword"
# Output: ~2.1s
# Measure response time for a non-existent account
curl -s -o /dev/null -w "%{time_total}\n" \
-X POST "http://<target>:9191/app" \
-H "Origin: http://<target>:9191" \
--data "service=direct/1/Home/%24Form&inputUsername=zz_doesnotexist_zz&inputPassword=wrongpassword"
# Output: ~0.2s
Essa descoberta é mais impactante quando usada como primeiro passo de um ataque em duas etapas:
Etapa 1 (CVE-2026-8794, esta descoberta) — Construir uma lista de nomes de contas válidas do PaperCut NG medindo as respostas de autenticação. Em ambientes corporativos, uma pequena wordlist de combinações firstname.lastname obtidas de fontes públicas (LinkedIn, site da empresa, rodapés de e-mail) costuma ser suficiente.
Etapa 2 (CVE-2026-8793) — Enviar tentativas ilimitadas de senha contra contas válidas confirmadas. A ausência de limitação de taxa ou bloqueio significa que qualquer ataque de credential stuffing ou password spraying pode ser conduzido inteiramente online, em velocidade total.
Um atacante não autenticado com acesso de rede ao TCP/9191 pode:
Em implantações corporativas típicas, os nomes de usuário do PaperCut espelham as contas do Active Directory. Portanto, um nome de usuário válido confirmado no PaperCut também é um nome de conta de domínio válido confirmado, ampliando o valor de reconhecimento para além do próprio PaperCut.
Para administradores (mitigações provisórias):
Para o fornecedor:
Realize uma comparação bcrypt fictícia em tempo constante quando o nome de usuário informado não corresponder a nenhuma conta, garantindo que os tempos de resposta sejam equalizados independentemente de a conta existir:
# Pseudocode — constant-time authentication pattern
user = db.find_user(username)
if user:
valid = bcrypt.verify(password, user.password_hash)
else:
bcrypt.verify(password, DUMMY_HASH) # always run, result discarded
valid = False
Esse é um padrão bem estabelecido para mitigar a CWE-208 em fluxos de autenticação.
| Data | Evento |
|---|---|
| 9 de maio de 2026 | Relatório inicial enviado à equipe de segurança do PaperCut |
Divulgado de acordo com os princípios de divulgação responsável. Todos os detalhes técnicos foram compartilhados com a equipe de segurança do PaperCut antes da divulgação pública.
Pesquisador: Vivien LEBAS — @Hazaz
| Condição | Mín (s) | Máx (s) | Média (s) | Desvio Padrão |
|---|
Conta existente (admin) | 2.08 | 2.19 | 2.13 | 0.031 |
Conta inexistente (zz_doesnotexist_zz) | 0.18 | 0.24 | 0.21 | 0.018 |
| Diferença | ~1.92s |
| 10 de maio de 2026 | Confirmação de recebimento |
| Maio de 2026 | CVE-2026-8794 atribuída pelo PaperCut (CNA) |
| Agosto de 2026 | Correção lançada — PaperCut NG 26.0.3 |
| Agosto de 2026 | Divulgação pública coordenada com o fornecedor |