Incidentes e Vulnerabilidades
Vazamento da Codecov (2021) — quando uma 'ferramenta confiável' no CI foi sequestrada e segredos vazaram
Em 2021, o Bash Uploader da Codecov (um script curl|bash executado no CI) foi alterado na origem e vazou segredos de CI de clientes por cerca de 2 meses; uma verificação de checksum o pegou. A cadeia como mapa de defesa, e as correções: verificar artefatos baixados, segredos de CI de menor privilégio, rotação.
Lemos incidentes públicos reais não como reprises de notícias, mas pela ótica de "como você se defenderia disso". Este artigo é baseado em registros públicos (o post-mortem oficial, a CISA, análise de fornecedores de segurança), citados ao final.
- Alvo
- Codecov (ferramenta de cobertura de código) e o CI de seus clientes
- Divulgado
- 15 de abril de 2021 (alteração desde 31/jan / detectado em 1º/abr)
- Classe
- Ataque à cadeia de suprimentos (alteração na origem de um artefato confiável) + roubo de segredos de CI
- Escala
- muitos dos clientes da Codecov (até ~29.000). Impactos à jusante na HashiCorp, Twilio, Rapid7
- Causa raiz
- o CI executou um artefato baixado sem verificação + o manuseio de chaves do fornecedor + segredos de CI superexpostos
- Correção real
- verificar artefatos baixados, segredos de CI de menor privilégio, rotação, monitoramento de egress
O que aconteceu (em termos simples)
Muitas equipes baixam e executam ferramentas externas tal como estão no seu CI, como curl … | bash. O Bash Uploader da Codecov era um script desse tipo.
O invasor explorou uma fraqueza na distribuição da Codecov para reescrever o próprio script distribuído, de modo que, ao rodar no CI, ele enviasse as variáveis daquele ambiente (segredos) para um servidor externo. Para o cliente, ele apenas invocou a ferramenta confiável como sempre. Como nenhuma linha do seu código mudou, quase não há sinal de que algo está errado.
Cerca de dois meses depois, um cliente comparou o checksum (SHA256) do script com o valor oficial e encontrou uma divergência — foi aí que a alteração veio à tona. As informações que podiam vazar incluíam chaves de nuvem, chaves de deploy, chaves de API e tokens, e a partir daí o ataque se encadeou para vazamentos à jusante em empresas como HashiCorp e Twilio.
É assustador justamente porque 'seu código está intocado'
Ataques à cadeia de suprimentos miram não o código que você escreveu, mas as coisas em que você confia e que puxa para dentro. Por isso, revisão de código e logs raramente os pegam. "Nós confiamos nisso" = "nós não verificamos isso" torna-se o buraco.
A cadeia também é um mapa de defesa
O que importa é que esta foi uma cadeia de quatro saltos, e cada salto tinha um ponto para interrompê-la. Leia isto como "onde ela poderia ter sido cortada", não como uma receita de ataque.
① Executar uma ferramenta confiável via curl | bash (conteúdo não verificado)
⊘ pare: fixar + verificar checksum do artefato baixado / vendoring
② O artefato é trocado 'na origem' (upstream)
Seu código está intocado, então você não tem como perceber.
⊘ pare: compare contra um hash conhecido-bom; use uma versão fixada
③ Variáveis de ambiente do CI (segredos, chaves, tokens) são enviadas para fora
⊘ pare: segredos de CI de menor privilégio, por etapa (não passe todo o env)
④ Chaves roubadas se encadeiam para produção e outros serviços
⊘ pare: rotação rotineira de chaves + monitoramento de egress (saída)
Linha do tempo divulgada
2021-01-31
Começa a alteração do Bash Uploader (intermitentemente daí em diante).2021-03–
Segredos fluem para fora do CI dos clientes por semanas, sem ser notado.2021-04-01
Um cliente encontra uma divergência de checksum e a reporta.2021-04-15
A Codecov divulga publicamente; aconselha os clientes a rotacionar todos os segredos.2021-04–
Surge o impacto à jusante na HashiCorp, Twilio, Rapid7. A Codecov depois aposenta o Bash Uploader.
A causa raiz não é um único erro
Atribua isso à "culpa da Codecov" e se repetirá. O lado do cliente também tinha camadas cedendo.
Como estava (na época)
- O CI executava um artefato baixado sem verificação (confiando no
curl | bash) - Segredos de CI superexpostos (toda etapa vê toda variável de ambiente)
- Segredos raramente rotacionados (chaves roubadas permanecem válidas por muito tempo)
- Tráfego de saída do CI sem monitoramento
Como deveria ser (prevenção)
- Fixar + verificar checksum de artefatos baixados, ou incorporá-los via vendoring
- Passar segredos de CI com menor privilégio, apenas para as etapas que precisam
- Rotacionar segredos regularmente (vida curta mesmo se vazarem)
- Monitorar o egress do CI e detectar envios para destinos desconhecidos
'Confiança' vem acompanhada de verificação
Ataques à cadeia de suprimentos miram as coisas em que você confia e puxa para dentro — bibliotecas de dependência, ferramentas de CI, imagens de build. O caso do XZ Utils tinha o mesmo formato. Minimize a confiança e verifique a integridade do que você puxa para dentro, por máquina.
Prevenindo isso no seu ambiente
Correções priorizadas que funcionam em qualquer escala. Faça um inventário de "o que o seu CI confia e executa" uma vez e isso se torna pessoal.
Verifique artefatos baixados (não confie cegamente em curl|bash)
Se o CI puxa um script ou binário externo, exija uma versão fixada (tag/commit) + verificação de checksum (SHA256). Onde possível, incorpore-o ao seu próprio repositório via vendoring. Este vazamento foi pego exatamente por essa verificação.
Restrinja os segredos de CI ao menor privilégio
Não passe toda variável de ambiente para toda etapa. Passe apenas o segredo necessário para o job/etapa necessário. Use tokens de vida curta (ex.: OIDC) para reduzir chaves de longa duração em repouso.
Rotacione segredos regularmente
Se roubado, uma vida curta limita o dano. Torne a rotação rotineira, e rotacione imediatamente quando um incidente de cadeia de suprimentos for reportado.
Monitore o egress do CI (tráfego de saída)
Seja capaz de detectar envios para destinos desconhecidos a partir do CI. Mesmo que a entrada não seja interrompida, mantenha uma camada que perceba a exfiltração.
A postura deste site: minimizar a confiança, verificar
Este site projeta a entrada de suas dependências e builds para ser verificada por máquina. O que a Codecov e o XZ Utils mostram é a mesma coisa — "nós confiamos nisso" tende a virar "nós não verificamos isso", e essa é a porta para ataques à cadeia de suprimentos. Reduza a confiança e confirme mecanicamente a integridade do que você puxa para dentro.
Fontes (registros públicos)
Os fatos aqui são baseados nas seguintes informações públicas, focadas em lições defensivas — não em passos de reprodução ou no código alterado.
- Codecov, "Post-Mortem / Root Cause Analysis (April 2021)" — about.codecov.io
- Codecov, "Bash Uploader Security Update" — about.codecov.io
- CISA, "Codecov Releases New Detections for Supply Chain Compromise" (2021) — cisa.gov
- Rapid7, "Analysis of the Codecov Supply Chain Compromise" (2021) — rapid7.com
Leia em seguida
FAQ
QQual foi a causa raiz do incidente da Codecov?
Não foi um bug no seu código, mas uma ferramenta externa confiável que você executa no CI (o Bash Uploader da Codecov) sendo alterada na sua origem (upstream). O CI baixava o script via curl e o executava sem verificar o conteúdo, então a versão alterada rodou e variáveis de ambiente do CI (segredos) foram enviadas para fora.
QPor que passou despercebido por cerca de 2 meses?
Porque o que foi alterado era a ferramenta de outra pessoa — o seu próprio repositório e código ficaram intocados, e não há uma anomalia evidente nos logs. Foi finalmente pego quando um cliente comparou o checksum (SHA256) do script com o valor oficial e encontrou uma divergência.
QIsso importa para projetos pequenos?
Sim. Puxar ferramentas para o CI via 'curl … | bash' é comum mesmo em solo, e se isso for sequestrado, seus segredos de CI são levados de uma só vez. As defesas aqui (fixar + verificar checksum de artefatos baixados, segredos de CI de menor privilégio, rotação regular) funcionam em qualquer escala.