A Parte 1 dissecou o bug e a Parte 2 (em breve) trata das pontes de rede. Esta trata do processo. Reportei um RCE pré-autenticação com PoC reproduzível, e ele foi fechado como Duplicate de um achado classificado como Informative — uma combinação logicamente contraditória. A severidade foi reduzida de 9.8 (crítica) para 2.2 (baixa) sem vetor CVSS nem justificativa técnica. Meus pedidos de divulgação foram cancelados "pending final check" que nunca chegou, e minhas perguntas sobre a política de bounty ficaram sem resposta. Analiso essas falhas de processo sem nomear pessoas — e, com igual honestidade, reconheço o contexto que as cerca: um programa de bug bounty colapsando sob uma enxurrada de reports gerados por IA.
Este é o meu relato factual de uma linha do tempo que documentei, no espírito da divulgação coordenada. Minha crítica é dirigida ao processo, não a indivíduos: refiro os triadores por seus papéis ("o triador", "a equipe"). Conduzi a pesquisa técnica em laboratório isolado. Não quero constranger ninguém — quero discutir, abertamente, como triagem e severidade deveriam funcionar.
📚 Parte 3 de 3 — Série PoisonJar
A Parte 1 dissecou a vulnerabilidade (RCE pré-auth via deserialização insegura). A Parte 2 (em breve) detalha as pontes de ataque via rede. Esta Parte 3 encerra a série olhando para o que aconteceu depois do report: a triagem.
Como a Divulgação Coordenada Deveria Funcionar
Antes de criticar, é justo estabelecer as regras do jogo. A divulgação coordenada de vulnerabilidades (CVD) é um acordo: o pesquisador reporta em privado e dá tempo para a correção; o fornecedor avalia, corrige e, idealmente, credita e divulga. Em plataformas como a HackerOne, esse fluxo passa por estados bem definidos:
| Estado | Significado |
|---|---|
| New | Recebido, aguardando triagem |
| Triaged | Validado pela equipe — é um problema real e reproduzível |
| Duplicate | Já existe outro report do mesmo problema — implica reconhecimento de que o problema existe |
| Informative | Útil, mas sem impacto de segurança acionável — não é tratado como vulnerabilidade |
| Resolved | Corrigido |
O CVSS é a linguagem comum de severidade. Sua força está em ser auditável: toda nota deriva de um vetor explícito (vetor de ataque, privilégios necessários, impacto em confidencialidade/integridade/disponibilidade…). Uma nota sem vetor é uma opinião; uma nota com vetor é um argumento que pode ser checado — e contestado. Guarde isso: será o centro de duas das três falhas a seguir.
A Política de Recompensa (e Onde o Achado se Encaixava)
Não muito antes deste report, o fornecedor havia dobrado as recompensas do seu programa de bug bounty, chegando ao topo de US$ 10.000 para execução remota de código (RCE). Um RCE pré-autenticação, com PoC funcional e cadeia completa demonstrada, é precisamente o tipo de achado que ocupa o topo desse tier.
Não se trata de "exigir dinheiro" — deixo isso explícito. Trata-se de consistência: se submeti um achado dentro da janela de uma política, a forma como ele é avaliado não deveria mudar conforme essa política expira. A ausência de uma resposta clara sobre a retroatividade transforma uma questão administrativa simples em mais uma zona cinzenta.
A Linha do Tempo Documentada
Os fatos, parafraseados a partir da própria thread do report. É a espinha de evidência deste artigo — tudo o que vem depois apenas interpreta esta sequência.
| Data | Evento |
|---|---|
| 27 Mar | Submeti o report: RCE pré-auth via deserialização no cache do TaskProcessing, com PoC e vídeos |
| 27 Mar | Enviei anexos adicionais (exploit, docker-compose, README) e informei o uso de LLM com reprodução manual |
| 27 Mar | A equipe fechou o report como Duplicate de um achado Informative (CVSS 4.7), descrito como "unserialize genérico" |
| 27 Mar | Contestei: a cadeia RCE completa e confirmada é um achado distinto e de maior severidade que o sink genérico |
| 31 Mar | Pedi a divulgação (citando a política da HackerOne: informative tratado como resolvido para fins de disclosure) |
| 10 Abr | A equipe cancelou meu pedido de divulgação — "refraining until final check" |
| 10 Abr | A equipe alterou a severidade de 9.8 (crítica) para 2.2 (baixa) — sem vetor nem justificativa |
| 22 Abr | Perguntei sobre a retroatividade do bounty (meu report é anterior ao fim do programa) — sem resposta |
| 08 Mai | Pedi novamente a divulgação / reabertura — só por clareza sobre o status do "final check" |
O Paradoxo "Duplicate + Informative"
Aqui está a primeira contradição, e ela é lógica, não emocional. Os dois rótulos puxam em direções opostas:
- Duplicate diz: "já sabemos disso, existe outro report do mesmo problema" — ou seja, o problema é reconhecido.
- Informative diz: "isto não tem impacto de segurança acionável" — ou seja, não é uma vulnerabilidade.
Algo não pode ser, ao mesmo tempo, "um problema de segurança conhecido o suficiente para ser duplicado" e "não um problema de segurança". E há um detalhe que aprofunda a inconsistência: o report-pai tinha CVSS 4.7 (Medium). Alguém, em algum momento, já considerou essa classe de bug como de severidade média. Tratá-la como meramente informativa entra em conflito com a própria pontuação que a acompanha.
O ponto técnico do dedup: o report-pai descrevia um padrão genérico de
unserialize — o sink. O report do PoisonJar demonstrava uma cadeia de
exploração completa e confirmada: cache poisoning → gadget FileCookieJar
→ bypass de .htaccess → webshell → RCE. Dedupar uma cadeia explorável com
PoC sob um sink teórico é, no mínimo, discutível. O sink é a porta; a cadeia é
a prova de que a porta abre.
A Redução de CVSS sem Justificativa Técnica
Vou começar admitindo o meu lado: eu posso ter exagerado no 9.8. Reduzir a severidade de um achado é absolutamente legítimo — e muitas vezes o pesquisador (eu, inclusive) superestima o impacto. O problema aqui não é a redução em si; é a ausência do raciocínio por trás dela à época (ver a atualização no fim desta seção). A nota saltou de 9.8 para 2.2 sem um vetor CVSS revisado, sem apontar qual métrica mudou e por quê.
| Nota | Leitura | Problema |
|---|---|---|
| 9.8 | Meu score original — RCE remoto, sem privilégios, sem interação | Exagerei um pouco: um 9.8 "perfeito" ignora a pré-condição de acesso ao cache |
| 2.2 | Score do vendor — impacto quase irrelevante | Subestima e sem vetor: ignora que o fim é RCE como www-data |
| ≈ 8.8 | RCE pré-auth com a pré-condição refletida no vetor | A nota honesta — ainda Alta/Crítica, e defensável com um vetor publicado |
E dá pra ser preciso — CVSS é um vetor, não um chute. Aqui está o meu, lado a lado com as variações defensáveis:
original (9.8) : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
honest (8.8) : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H <- AV:N -> AV:A (preciso estar na rede do Redis)
scope-Δ (9.6) : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H <- cache poisoning cruza a fronteira de confianca
high-AC (8.1) : CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H <- piso, se a config no-auth contar como complexidade
A única correção honesta ao meu exagero é AV:N → AV:A (preciso de acesso de
rede ao Redis), e isso me leva a 8.8. Se eu modelar o cache poisoning como
mudança de escopo (S:C), sobe para 9.6. No piso mais conservador
(AC:H), ainda é 8.1. De qualquer ângulo defensável, o número fica
entre 8.1 e 9.6 — nunca perto de 2.2.
Sendo honesto: um score perfeito pressupõe zero atrito, e aqui existe uma pré-condição real — o acesso de escrita ao cache. Refletindo isso no vetor (o acesso adjacente ao Redis), a nota justa cai para 8.8 — ainda Alta/Crítica, porque o resultado final é RCE pré-autenticação como www-data. Ou seja: a equipe estava certa em reduzir; errou no quanto e no como. De 9.8 para 8.8 há um argumento técnico defensável; de 9.8 para 2.2, sem vetor revisado e sem explicação no momento, não havia — ainda mais quando a fronteira de confiança (tratar o Redis como entrada não confiável num cenário Kubernetes/VPC) puxa a nota para cima, não para baixo.
"Uma nota de CVSS sem vetor não é uma avaliação — é um veredito. E vereditos sem fundamentação são exatamente o que o CVSS foi criado para evitar."
— Análise ERSECURITY, Maio 2026O critério da HackerOne para a classificação
Depois da publicação deste artigo, a HackerOne — responsável pela atribuição do CVE — esclareceu o critério por trás da classificação: o achado não foi enquadrado como desserialização insegura porque o threat model adotado considera o Redis uma fonte de dados confiável, e não contempla o comprometimento do próprio Redis como parte do modelo. É a justificativa que não constava no momento do fechamento, e fica registrada aqui para que a posição do programa apareça nas palavras dele, e não apenas pela nota atribuída.
O Contrapeso Honesto: o Colapso por Spam de IA
Seria desonesto contar essa história sem o outro lado. Poucas semanas depois deste report, o fornecedor encerrou o programa de recompensas, citando publicamente uma enxurrada de reports de baixa qualidade gerados por IA — o fenômeno conhecido como "AI slop", que sufocou equipes de triagem do setor inteiro (Nextcloud, curl e outros relataram o mesmo).
E há uma ironia incômoda: no meu próprio report, declarei abertamente ter usado um LLM para auxiliar na análise de código-fonte e na escrita — ainda que com reprodução manual de todos os passos em laboratório. No meio de uma onda de spam de IA, essa transparência, paradoxalmente, pode ter ligado um alerta. É plausível que um RCE genuíno e reproduzível tenha sido varrido junto com o ruído.
Reconhecer tudo isso não absolve as falhas de processo — contextualiza. Um triador exausto ainda assim pode (e deve) publicar um vetor CVSS ao reduzir uma nota; ainda pode responder a uma disputa com uma frase. O "AI slop" explica a desconfiança inicial; não explica o paradoxo lógico nem o silêncio que se seguiu.
A Ausência de Respostas
A falha final é a mais simples de corrigir e, talvez por isso, a mais frustrante. O fluxo travou em um limbo:
- Cancelaram meu pedido de divulgação com a promessa de um "final check" — que nunca foi reportado como concluído.
- Meu report não foi reaberto, apesar do meu pedido explícito para documentar o resultado da reavaliação.
- Minha contestação técnica (cadeia ≠ sink genérico) não recebeu refutação técnica.
- Minha pergunta sobre a retroatividade do bounty ficou sem resposta.
Silêncio também é uma decisão — só que não documentada. Para mim, transformou um desfecho (mesmo que desfavorável) em um limbo indefinido: não há o que contestar, não há o que aprender, não há encerramento. Um simples "reavaliamos, mantemos a nota X pelo motivo Y" teria resolvido — técnica e humanamente.
Como Seria uma Boa Triagem
Crítica sem proposta é só reclamação. O que teria transformado este caso de um limbo em um encerramento saudável — para os dois lados:
| Para o Fornecedor | Para o Pesquisador |
|---|---|
| Publicar um vetor CVSS ao alterar uma nota | Documentar tudo — a linha do tempo é a evidência |
| Não combinar Duplicate com Informative sem explicar | Entregar um PoC reproduzível e um lab isolado |
| Responder a disputas com uma frase técnica | Separar o sink da cadeia de forma explícita |
| Honrar a política de disclosure de forma consistente | Gerenciar o ângulo "IA" — transparência sim, mas com provas manuais |
| Esclarecer a retroatividade de políticas que expiram | Manter o tom profissional, focado em processo |
Conclusão
A divulgação coordenada é uma relação, não uma transação. Quando funciona, todo mundo ganha: o fornecedor corrige, o usuário fica mais seguro, o pesquisador é creditado. Quando emperra — em um paradoxo de rótulos, numa nota sem vetor, num silêncio — a perda é mútua e o bug, a essa altura, virou detalhe. A integridade do processo importa tanto quanto a integridade do achado.
"Encontrar a vulnerabilidade foi a parte fácil. O mais difícil — e o mais educativo — foi entender que segurança não é só código: é processo, é confiança e é como lidamos com o desacordo quando ele aparece."
— Encerramento da Série PoisonJarCom isso, a série PoisonJar se fecha: do byte serializado ao fluxo de divulgação. Se houver uma única lição para levar, é esta — documente tudo. A linha do tempo que você guarda hoje é o argumento que você terá amanhã.
Recursos e Referências
| Tipo | Recurso | Link |
|---|---|---|
| 🤝 Processo | HackerOne — Coordinated Vulnerability Disclosure | Docs |
| 📊 CVSS | CVSS v3.1 — Specification & Calculator | FIRST.org |
| 💰 Bounty | Updates about the Nextcloud Bug Bounty Program | Blog Nextcloud |
| 📰 Imprensa | Nextcloud ends bug bounty over low-quality AI reports | Techzine |
| 🤖 Contexto | O fenômeno do "AI slop" em bug bounties | Cybernews |
| 🔗 Série | PoisonJar Parte 1 — A Vulnerabilidade | Ler Parte 1 |