← Latest Blog Posts

🎵 Spotify Podcast

Em 18 de novembro de 2025, a infraestrutura global de telecomunicações sofreu uma severa contração de conectividade, precipitada por uma falha catastrófica dentro da Cloudflare. O outage, que se estendeu por mais de quatro horas, a partir das 11:20 UTC, efetivamente particionou uma porcentagem significativa da economia digital de sua base de usuários. Serviços críticos, desde grandes plataformas de e-commerce (como Amazon e Shopify) até portais bancários e infraestrutura essencial de IA, ficaram inacessíveis, retornando erros generalizados da série HTTP 500. Embora os sintomas externos fossem semelhantes a um ataque DDoS em hiperescala – uma teoria favorecida inicialmente devido às recentes campanhas do botnet "Aisuru" – o evento precipitador foi estritamente interno.

Para compreender a magnitude dessa falha, é crucial reconhecer a arquitetura atual da internet. A noção de uma web descentralizada foi amplamente substituída por uma topologia altamente concentrada, dependente de poucos provedores de "Edge Cloud". Cloudflare atua como uma membrana inteligente e programável, sendo o proxy o plano de controle decisivo para o tráfego. O proxy é responsável por operações complexas como Terminação Criptográfica, Verificação de Identidade Zero Trust e Mitigação de Ameaças, incluindo o Gerenciamento de Bots em tempo real. Quando essa membrana se rompe, a disponibilidade do servidor de origem é irrelevante, pois o caminho de entrada é comprometido.

A raiz da falha técnica residiu em um paradoxo de permissões de banco de dados que levou a uma Incompatibilidade de Dados de Configuração. Cloudflare utiliza o ClickHouse, um sistema de gerenciamento de banco de dados orientado a colunas, para gerar inteligência operacional e análises em tempo real. O sistema de Gerenciamento de Bots dependia de uma consulta SQL ao cluster analítico para gerar arquivos de configuração. O gatilho ocorreu às 11:05 UTC, quando a engenharia iniciou uma implantação de mudança de permissão de banco de dados.

A falha fatal não foi um bug de código, mas sim uma consulta SQL implicitamente ampla. O sistema de Gerenciamento de Bots executava um trabalho ETL programado a cada cinco minutos para buscar metadados de recursos usando a consulta SELECT name, type FROM system.columns WHERE table = 'http_requests_features'. Crucialmente, essa consulta carecia de uma cláusula DISTINCT e de um filtro de banco de dados (WHERE database = 'default'). Antes da mudança de permissão, a conta de serviço só tinha visibilidade do banco de dados default. Após a atualização de 11:05 UTC, o serviço ganhou acesso explícito ou inadvertido ao esquema r0 subjacente (os shards físicos). O resultado foi que a consulta viu agora duas tabelas com o mesmo esquema (default.http_requests_features e r0.http_requests_features), duplicando efetivamente a lista de recursos de aproximadamente 60 para mais de 120.

Esse resultado de consulta inflado foi serializado em um artefato de configuração crítico, o "Feature File", que atua como o conjunto de instruções para o módulo de Gerenciamento de Bots na borda. A propagação dessa configuração corrompida foi o vetor da falha global. O impacto foi diferenciado: a arquitetura legacy (baseada em NGINX/Lua) provavelmente tratou o arquivo de configuração de forma mais flexível, resultando em "pontuações de bot aplicadas incorretamente" (degradação da segurança). No entanto, os modernos proxies FL2 (provavelmente baseados em Rust e projetados para desempenho e segurança estrita) aplicaram verificações de limites de memória rígidas. Quando o arquivo de recurso duplicado violou o limite hard-coded (o limite era 200, mas o esperado era $\sim 60$), o processo sofreu um panic – um mecanismo de "falha fechada" (fail-closed) que resultou em uma Negação Total de Serviço para o tráfego legítimo.

A natureza intermitente da falha ("flapping") complicou a resposta, pois o gerador de arquivos de recursos alternava entre nós de banco de dados atualizados (que geravam arquivos venenosos) e nós não atualizados (que geravam arquivos válidos), obscurecendo a correlação entre a mudança das 11:05 UTC e o outage global. A equipe de resposta a incidentes enfrentou um viés cognitivo, concentrando-se na hipótese de ataque externo (Aisuru), atrasando a investigação interna. A mitigação exigiu uma intervenção manual de alto risco para injetar um arquivo de configuração "conhecido como bom".

A lição fundamental reside no tratamento da configuração dinâmica como infraestrutura. O incidente validou o risco sistêmico da centralização. Para o futuro, as recomendações técnicas incluem a aplicação estrita do Princípio do Menor Privilégio ao impor a visibilidade do esquema (r0 deve ser invisível), a adoção de consultas SQL defensivas e estritamente limitadas (WHERE database = 'default'), e a exigência de um estágio de "Compilação" ou "Validação" de Configuração com testes de asserção de limite (assert(feature_count <= 200)) antes da distribuição. O incidente também reabriu o debate sobre a Disponibilidade versus Segurança: o design "Fail-Closed" do FL2 priorizou a segurança (prevenir a corrupção de memória), mas causou indisponibilidade global, sugerindo a necessidade de opções de "Degradação Elegante" ou "Fail-Open" para módulos não essenciais.