Resumo

  • Um transformador de HTML podia ler além do próprio buffer e colocar na resposta fragmentos de outras requisições, rompendo o isolamento esperado entre clientes do mesmo edge.
  • Desligar as funções e corrigir o parser encerrou novos vazamentos, mas cópias já armazenadas e credenciais potencialmente expostas exigiram uma recuperação separada que o patch não poderia certificar sozinho.

O domínio que acionava não era o dono dos dados

Em 17 de fevereiro de 2017, o Project Zero avisou a Cloudflare que algumas páginas continham material estranho ao conteúdo esperado. Havia cookies, tokens de autenticação, corpos de POST e outros trechos da memória do processo. Alguns resultados já tinham sido guardados por mecanismos de busca.

O nome Cloudbleed lembra o Heartbleed, mas a diferença estrutural importa. O defeito operava em um serviço compartilhado que transformava páginas de muitos clientes. O HTML anormal de um site podia abrir o caminho defeituoso, enquanto os bytes copiados para a resposta pertenciam à requisição de outro cliente.

Uma lista de domínios que acionaram o problema, portanto, não é uma lista de vítimas. O cliente não precisava usar a função vulnerável; bastava compartilhar o processo errado no momento errado. A regra rompida era maior que “interpretar esta página corretamente”: o trabalho de um inquilino jamais pode ler ou emitir a memória de outro.

Um buffer novo acordou um erro antigo

A Cloudflare encontrou o defeito em código antigo gerado com Ragel e usado por três transformações: ofuscação de e-mail, Server-Side Excludes e reescrita automática de HTTPS. A ausência de uma operação fhold podia deixar um ponteiro no fim do buffer. O chamador aceitava o retorno como uma faixa válida e copiava bytes depois do limite.

O aumento ocorreu após a implantação do parser cf-html, que mudou o comportamento dos buffers. A Cloudflare separou claramente os papéis: o erro não estava no Ragel nem no próprio cf-html. O componente novo mudou as condições ao redor do legado e tornou frequente um defeito que estava adormecido.

Revisar apenas o componente novo não cobre esse risco. A implantação precisa testar limites exatos, comparar as duas versões e investigar falhas de todos os consumidores antigos que a nova rota volta a exercitar.

Uma sequência de desligamento com horas exatas

O primeiro poder de resposta estava no operador do edge. A cronologia UTC detalhada registra o recebimento das informações às 00h32 de 18 de fevereiro, o desligamento mundial da ofuscação de e-mail às 01h19, o da reescrita automática de HTTPS às 04h24 e a implantação mundial do patch com a chave de cf-html às 07h22. Server-Side Excludes não tinha sua própria chave global; foi necessário construí-la e implantá-la.

Uma chave de emergência não é mera conveniência operacional. Ela integra a segurança da função. Sem ela, a equipe escreve código durante a crise. Com ela, uma transformação opcional pode ser sacrificada sem derrubar o proxy que não depende dela.

Segundo a Cloudflare, as chaves privadas SSL dos clientes não ficaram expostas por esse caminho porque a terminação TLS executava em outra instância do NGINX. A memória HTTP, porém, continha uma chave privada usada na criptografia entre máquinas da Cloudflare e alguns segredos internos de autenticação. O isolamento protegeu uma classe de alto impacto, mas não tornou vazio o conjunto de segredos alcançáveis.

A posterior reescrita em Rust tornou o acesso fora dos limites indisponível no caminho seguro normal. É uma regra local mais forte do que depender de revisão humana para cada ponteiro. Ela não prova autorização correta nem protege automaticamente bibliotecas inseguras ou um fluxo de dados mal desenhado.

A taxa era estimativa, não cadastro

O relatório inicial situou a maior exposição entre 13 e 18 de fevereiro e estimou cerca de uma requisição potencialmente vazada a cada 3,3 milhões, aproximadamente 0,00003%. O cálculo posterior estimou 1.242.071 acionamentos entre 22 de setembro de 2016 e 18 de fevereiro de 2017: 605.037 antes de 13 de fevereiro, vindos de menos de 180 sites, e 637.034 nos cinco dias finais, vindos de 6.457 sites.

Os limites da evidência acompanham os números. Logs detalhados representavam amostra de 1% e só existiam de 8 a 18 de fevereiro. Registros anteriores já tinham sido apagados; o período antigo foi modelado com análises agregadas e quedas. A Cloudflare não encontrou sinal de exploração maliciosa nos dados analisados, o que não prova que nenhuma exploração ocorreu.

Acionamentos não são vítimas únicas. Uma taxa global não mede a sensibilidade de um token. A ausência de rastro em uma amostra não encerra o passado.

O patch não recolheu os bytes enviados

Desativar as funções impediu novas respostas contaminadas, não removeu as entregues. A Cloudflare estimou que rastreadores de busca produziram mais da metade dos acionamentos, removeu mais de 80 mil páginas únicas de caches e encontrou em caches de terceiros dados associados a 150 clientes.

Esses valores não fixam o universo afetado. Nem toda página removida continha segredo; 150 clientes identificados não são um teto; uma limpeza não prova inexistência de cópias privadas. Contenção e recuperação têm critérios de conclusão diferentes.

O patch demonstra apenas que a rota conhecida parou de criar vazamento nas condições testadas. Operadores de cache precisam excluir seu material. Clientes precisam revogar ou substituir sessões, tokens, chaves de API e senhas em cada sistema que reconhecia essa autoridade. A prova é a rejeição do segredo antigo, não a emissão de um novo.

Um limite comum mínimo e escolhas locais reversíveis

A primazia do código em execução de Lu Heng exige resultado observável: o edge não emite memória cruzada, o estado das funções pode ser verificado, credenciais antigas falham e os controladores dos caches tratam os resíduos. A palavra “resolvido” não cria essas condições.

A especificação inicial mínima pode ser curta e absoluta: uma resposta contém apenas dados autorizados para aquela resposta. Transformações opcionais, parser, ritmo de implantação e desligamento permanecem escolhas locais. Elas podem mudar ou ser recusadas sem reduzir o isolamento comum ou obrigar todos os clientes a aceitar o mesmo risco.

O Cloudbleed não provou que infraestrutura compartilhada é inviável. Provou que o compartilhamento precisa de uma membrana rígida e que toda função opcional que a atravesse deve poder desaparecer antes do serviço inteiro.

Fontes