Resumo

  • Em 2 de julho de 2019, uma regra WAF funcionalmente aprovada foi distribuída pela Cloudflare ao mundo em segundos; o retrocesso catastrófico de uma expressão regular esgotou a CPU dos processos HTTP/HTTPS e causou erros 502 por 27 minutos.
  • Resiliência não exige abrir mão da reação global a uma ameaça ativa: exige separar essa exceção da mudança cotidiana, provar limites de recursos, ampliar a exposição em etapas e manter parada, autenticação e estado fora do domínio de falha da borda.

O sistema mais rápido não era o sistema errado

Às 13h31 UTC, uma solicitação de mudança aprovada foi incorporada ao código. Às 13h37, o TeamCity executou construção e testes. Às 13h42, um processo automatizado iniciou a distribuição de uma pequena alteração na detecção de XSS.

O Quicksilver, sistema de configuração da Cloudflare, entregou a alteração. Segundo o relatório, ele alcançava mais de 180 cidades, processava em média cerca de 350 mudanças por segundo e apresentava 2,29 segundos no percentil 99 de propagação mundial. Um texto posterior descreveu a mesma arquitetura em centenas de cidades.

Velocidade fazia parte da defesa. Uma WAF precisa colocar proteção diante de uma vulnerabilidade em exploração antes que a janela seja usada contra muitos clientes. A própria Cloudflare citou uma regra rápida para uma vulnerabilidade grave do SharePoint como prova dessa necessidade.

O problema foi outro: uma regra comum tinha acesso ao mesmo caminho de atuação mundial. Os testes demonstravam se os exemplos maliciosos eram bloqueados e se exemplos legítimos passavam. Não calculavam quanto trabalho uma entrada extrema poderia exigir.

Portanto, a revisão aprovou a resposta lógica, enquanto o mecanismo concedeu uma autoridade maior: executar a lógica sobre o tráfego de toda a rede. A propagação apagou a distância entre decisão e impacto antes que a observação conseguisse precificar a operação.

Há duas maneiras de uma regra estar correta

A expressão era avaliada por um motor baseado em PCRE. Motores de retrocesso exploram alternativas até estabelecer uma correspondência. Na maioria das situações, isso é eficiente. Certas combinações de repetição e ambiguidade, porém, fazem o número de caminhos crescer de modo exponencial.

O resultado final pode continuar correto. O custo para alcançá-lo é que destrói o serviço.

Uma regra precisa, assim, satisfazer dois contratos. O contrato semântico define o que bloquear. O contrato operacional limita CPU, memória e espera que qualquer entrada pode consumir. Um conjunto de exemplos funcionais não prova o segundo.

O WAF estava no caminho de atendimento HTTP/HTTPS e executava milhares de regras em enorme volume. A nova expressão consumiu a capacidade dos processos que entregavam tráfego. Proxy, CDN e WAF foram atingidos ao mesmo tempo.

Os servidores web da frente ainda possuíam núcleos disponíveis para gerar páginas 502, mas não alcançavam os processos responsáveis por HTTP/HTTPS. Dizer que toda máquina ficou sem CPU apaga essa arquitetura: a casca que informava o erro sobreviveu; a camada que fazia o serviço funcionar não.

O pós-incidente também registrou uma proteção de CPU que existira e fora removida por acidente durante uma refatoração de desempenho. Somaram-se a ela um motor sem garantia contra essa complexidade, testes sem detecção de consumo descontrolado e um procedimento sem estágios para regras não emergenciais. “Uma expressão ruim” é fato, mas não é explicação suficiente.

O alarme começou depois da convergência

Às 13h45, três minutos depois do início do envio, um teste sintético externo do WAF gerou o primeiro PagerDuty. Falhas em outros testes ponta a ponta, queda global de tráfego, erros 502 e avisos de exaustão de CPU nos PoPs vieram em seguida. A nota inicial diz que, no pior momento, o tráfego da Cloudflare caiu 82%. O número não descreve 82% da Internet.

Nos primeiros minutos, a equipe considerou um ataque desconhecido. Às 14h00, métricas, registros e strace indicavam o WAF, descartando o ataque. Às 14h02, a sala discutiu um global terminate, mecanismo para desligar um componente no mundo todo.

O retorno comum não acompanhava a velocidade de ida. Recuperar o conjunto anterior exigiria duas construções completas do WAF. A ação viável foi mais ampla: retirar o WAF inteiro, investigar a regra, testar e só então restaurar.

O acesso operacional também dependia da área afetada. A Cloudflare usava Access na autenticação interna. O painel habitual, Jira e o sistema de construção ficaram difíceis de alcançar. Um desvio pouco exercitado precisou ser usado; alguns engenheiros de confiabilidade descobriram credenciais expiradas por uma medida de segurança associada ao desuso.

O comando mundial foi executado às 14h07. Às 14h09, CPU e tráfego voltaram aos níveis esperados; outros mecanismos de proteção continuaram ativos. Depois, a empresa retirou o tráfego de clientes pagantes de uma cidade e usou ali uma amostra para testes positivos e negativos. Às 14h52, reativou o WAF globalmente.

O relatório detalhado registra 27 minutos de indisponibilidade; a nota curta fala em cerca de 30. A diferença é compatível. A discrepância decisiva estava entre segundos para conceder autoridade e dezenas de minutos para retirá-la, com a restauração específica ainda mais distante.

Limitar a linguagem reduz o raio do erro

Entre as medidas, a Cloudflare prometeu recolocar a proteção de CPU, revisar as 3.868 regras, adicionar perfis de desempenho e migrar para RE2 ou um motor em Rust. Em julho de 2020, informou que o WAF havia passado, ainda em julho de 2019, de uma base PCRE para um motor inspirado em RE2.

RE2 declara segurança como objetivo primário. O tempo de correspondência é assintoticamente linear no tamanho da entrada, a memória opera sob orçamento configurável e a exaustão falha de modo controlado. Para isso, não implementa referências anteriores e certas verificações de contexto quando elas dependem de retrocesso.

Essa escolha retira uma parcela de poder antes da revisão. Algumas construções deixam de ser convenientes ou precisam ser reescritas; em troca, um lapso do autor não cria a mesma árvore exponencial. A linguagem de regras passa a ser uma fronteira de capacidade.

RE2 não promete ganhar todas as disputas de velocidade. Expressões complexas têm fatores constantes, e a migração pode exigir redesenho. PCRE2 também oferece limites de correspondência, profundidade e heap. As fontes não demonstram que esses controles estivessem ativos no trajeto da Cloudflare em 2019.

O resultado posterior é instrutivo: a troca do motor não produziu diferença mensurável de CPU média, mas reduziu valores extremos nos percentis 95 e 99 de tempo. Segurança de disponibilidade estava na cauda. Não era necessário tornar todo pedido barato; era necessário impedir que um pedido se tornasse absurdamente caro.

Ainda há transformações, decodificação, tokenização, cache e interação de regras ao redor da expressão. Um avaliador limitado não substitui orçamento para a cadeia inteira, carga representativa e exposição gradual.

Preservar a via de emergência sem torná-la rotina

A Cloudflare passou a distinguir implementação em estágios para mudanças normais e distribuição global imediata para ataques ativos. Essa distinção conserva o valor do WAF e reduz a autoridade diária.

Uma regra comum pode passar por análise de complexidade, entradas adversas e medição do caminho completo; operar em observação sem bloquear; avançar para uma cidade, pequena fração de tráfego e região. A promoção deve combinar eficácia, CPU por regra, latência de cauda, erros e alcance dos processos, com interrupção automática.

A exceção de emergência encurta a observação, mas precisa de incidente identificado, fundamento de ameaça, dono, expiração, orçamento vivo e outra pessoa com poder de revogar. Urgência é uma decisão explícita entre riscos, não ausência de regra.

O estágio deve conter de verdade. Cinco por cento de locais que compartilham fila, capacidade ou telemetria vulnerável não formam um canário útil. Tráfego representativo, capacidade separada e grupo de controle são parte do teste.

Retirar uma regra também deve ser mudança de estado imediata, não reconstrução dupla. Uma chave desliga a regra; outra, o componente. Ambas precisam funcionar sem o painel, a identidade e a construção usuais.

O comando precisa sobreviver ao que comanda

O uso de serviços próprios não iniciou o incidente, mas tornou a recuperação mais difícil. Painel e API dos clientes também passavam pela borda atingida. A capacidade de agir diminuía junto com a disponibilidade.

Independência pode ser estreita: autenticação de emergência, estado público, término global, configuração mínima, acesso a evidências e controles para reduzir perdas. Essa superfície precisa de capacidade, rota e credenciais isoladas e regularmente exercitadas.

A primazia do código em execução, proposta por Heng Lu, separa declaração e realidade. Revisão, ticket e plano de retorno organizam a mudança; não limitam CPU por si. Quando o código real consome a máquina e fecha o caminho de controle, o rótulo de aprovado não oferece proteção.

Da mesma forma, controle técnico não garante controle prático. Ter uma ordem de desligamento é insuficiente se autenticação, pessoal, console e construção dependem do componente. Poder operacional é a capacidade de agir durante a falha.

Limites da evidência

A cronologia, a arquitetura e as causas vêm principalmente da própria Cloudflare. A transparência permite esta análise, mas continua sendo um relato da empresa. Não há nas fontes uma contagem externa completa de clientes, domínios, pedidos ou perdas econômicas.

A Cloudflare disse expressamente que não se tratou de ataque. Este texto não atribui intenção adversária nem acionamento deliberado. O Quicksilver não escreveu a expressão nem removeu a proteção; ampliou a consequência porque a aprovação comum podia usar sua capacidade integral.

O texto de 2020 confirma a migração do motor e resultados medidos na cauda, mas não prova a permanência de cada correção anunciada em 2019. O caso sustenta um modelo de controle, não a infalibilidade futura de empresa ou tecnologia.

Fontes