Exploit de vulnerabilidade no CodeRabbit: de um PR simples até RCE e obtenção de permissão de escrita em 1 milhão de repositórios
(research.kudelskisecurity.com)- A equipe de pesquisa de segurança conseguiu execução remota de código (RCE) nos servidores de produção do CodeRabbit e vazamento de tokens de API e segredos
- Com um PR usando Rubocop, foi possível roubar variáveis de ambiente, além de acessar o PostgreSQL e ler/escrever em 1 milhão de repositórios
- Com o vazamento da chave privada do GitHub App, tornou-se possível injetar código malicioso e modificar código-fonte em larga escala, incluindo repositórios públicos e privados
- A equipe do CodeRabbit respondeu imediatamente em poucas horas após o reporte da vulnerabilidade e reforçou as medidas de segurança
- Ao executar ferramentas externas, destaca-se a necessidade de prevenir incidentes de segurança com isolamento em sandbox, princípio do menor privilégio e bloqueio de rede
Introdução
- Em janeiro de 2025, a equipe de pesquisa da Kudelski Security divulgou uma vulnerabilidade grave no CodeRabbit
- No CodeRabbit, amplamente usado como ferramenta de automação de revisão de PRs, foram confirmados problemas críticos como remote code execution (RCE), vazamento de variáveis de ambiente e informações sensíveis, e obtenção de permissão de leitura/escrita em mais de 1 milhão de repositórios
- Este texto traz uma análise detalhada da vulnerabilidade pública apresentada na Black Hat USA e tem alto valor como caso real de falha em ferramentas de revisão baseada em código e sistemas integrados
- A vulnerabilidade reportada foi corrigida rapidamente logo após a notificação
Visão geral do CodeRabbit
- O CodeRabbit é o aplicativo de revisão de código com IA mais instalado no GitHub/GitLab Marketplace
- Nas duas plataformas, ele revisa 1 milhão de repositórios e 5 milhões de pull requests
- Sempre que o usuário cria ou atualiza um PR, o mecanismo de IA analisa o código e gera automaticamente comentários e sugestões
- Ele traz ganhos significativos de produtividade de desenvolvimento, como resumo de código, detecção de vulnerabilidades de segurança, sugestões de melhoria e geração de diagramas
Uso do CodeRabbit e estrutura de permissões
- O plano Pro oferece integração com ferramentas de linter e SAST (análise estática)
- Ao autenticar a conta do GitHub e instalar o app, o usuário concede permissão de leitura e escrita aos repositórios selecionados
- Se esse modelo de permissões for explorado de forma maliciosa, ele pode causar impacto direto no código de todos os repositórios onde o app estiver instalado
Execução de ferramentas externas e descoberta do exploit
- Quando detecta alterações de código em um PR, o CodeRabbit executa automaticamente várias ferramentas externas de análise estática (ex.: Rubocop)
- O Rubocop foi projetado para usar o arquivo de configuração
.rubocop.ymla fim de carregar arquivos externos de extensão Ruby (ext.rbetc.)- O atacante insere código malicioso em
.rubocop.ymleext.rb, envia um PR e induz o CodeRabbit a executar esse código em seu servidor remoto
- O atacante insere código malicioso em
- O código executado por essa técnica envia todas as variáveis de ambiente do servidor para o servidor do atacante
Análise do conteúdo vazado das variáveis de ambiente
- As variáveis de ambiente vazadas continham API keys, tokens e senhas de diversos serviços, incluindo:
- chaves de API da Anthropic/OpenAI, salt/senha de criptografia, chave privada do GitHub App, informações de conexão com PostgreSQL etc.
- Com RCE, os danos secundários podem ser grandes e de alto impacto, incluindo acesso ao banco de dados, alterações de código e vazamento de informações internas do serviço
- Seria possível aprofundar a exploração maliciosa no servidor real, mas, considerando a operação do serviço, a verificação foi interrompida após o mínimo necessário
Obtenção de permissão de leitura/escrita em 1 milhão de repositórios
- Foi possível autenticar na API do GitHub usando o GITHUB_APP_PEM_FILE (chave privada) presente nas variáveis de ambiente
- Em todos os repositórios aos quais o CodeRabbit podia acessar, incluindo públicos e privados, seria possível exercer permissões extremamente poderosas, como:
- leitura/escrita de código-fonte, substituição de arquivos de release (ataque à cadeia de suprimentos) e alteração do histórico git
- O código de reprodução (PoC) foi divulgado, comprovando a viabilidade de exploração real
Resumo da PoC
- Usando bibliotecas como PyGitHub e a chave privada vazada, o App ID etc., foi possível emitir tokens de acesso arbitrários para repositórios
- Com esses tokens, torna-se possível automatizar clonagem de repositórios privados, alteração de arquivos, novos commits e adulteração de arquivos de release
Possibilidade de comprometimento dos repositórios internos/privados do CodeRabbit
- Como a própria organização do CodeRabbit também utilizava a instalação do serviço, também seria possível acessar e clonar os repositórios internos de código-fonte do CodeRabbit
- Bastava conhecer o nome da organização para consultar o installation ID e então acessar imediatamente a lista de repositórios correspondente
Resumo do impacto
- Acesso não autorizado a repositórios privados e vazamento de dados pessoais
- Ameaça de ataques à cadeia de suprimentos, como manipulação de código-fonte e inserção de malware/backdoors
- Possibilidade de encadear com vulnerabilidades adicionais, como GitHub Actions
- A RCE direta pode causar destruição de dados, indisponibilidade do serviço e danos em cascata a outros serviços
Contexto e limites do julgamento da IA
- Mesmo durante o ataque, o próprio PR foi revisado normalmente pelo CodeRabbit, e embora tenha deixado comentários de alerta sobre vulnerabilidade, não conseguiu identificar de fato o trecho malicioso
- Isso mostra que uma ferramenta de revisão de código com IA não necessariamente compreende o contexto completo de uma situação de risco real
Resposta e recomendações
- O CodeRabbit desativou o Rubocop, trocou segredos e realizou auditoria do sistema em poucas horas após o reporte da vulnerabilidade
- O problema ocorreu em uma ferramenta sem sandbox aplicada (Rubocop) e, após as medidas, o sistema foi melhorado para executar todas as ferramentas externas em ambientes isolados
- Para reforçar a segurança, destaca-se a necessidade de design defensivo no ambiente de execução de ferramentas externas, com minimização de variáveis de ambiente, restrição de IPs com acesso à rede e bloqueio de acesso à internet
Divulgação responsável e conclusão
- Em janeiro de 2025, após o reporte, houve resposta e correções rápidas
- Ficou apenas na PoC, mas confirmou-se que um atacante malicioso poderia explorar isso facilmente para selecionar repositórios de alto valor, realizar ransomware em larga escala ou ataques destrutivos à cadeia de suprimentos
- Reforça-se a importância de implementar sandbox e o princípio do menor privilégio ao integrar ferramentas externas de análise e serviços automatizados baseados em IA
1 comentários
Comentários no Hacker News
Nossa, essa é uma vulnerabilidade realmente séria. Ainda bem que foi corrigida desta vez, mas o fato de um problema desses ter existido em primeiro lugar já é um problema. Ao construir um sistema em plataforma de nuvem que analisa código de usuário, a regra mais básica é que o analisador deve sempre rodar em um ambiente isolado. Injeção direta de código pode acontecer por meio de plugins, e linters/analisadores/compiladores são softwares complexos com uma grande superfície de ataque. Nunca se deve assumir que é seguro executar essas ferramentas em um ambiente compartilhado sobre repositórios arbitrários. Eu também operei uma plataforma de análise de código, e mesmo quando rodávamos analisadores desenvolvidos por nós diretamente nos repositórios dos clientes, o sistema foi projetado para funcionar em ambiente sandbox. Não incluíamos variáveis de ambiente nem permissão para requisições de rede, mas a análise ainda assim só era executada dentro do sandbox. É a única forma de fazer análise de código com segurança
https://github.com/getgrit/gritql
Cancelei minha assinatura paga do Coderabbit. Sempre me preocupa quando uma empresa só admite um problema depois que ele viraliza no HN. Em nenhum lugar do blog oficial há menção a essa vulnerabilidade, e hoje também não há nenhum post novo. Acho que qualquer um pode cometer erros, mas quando algo assim acontece, não divulgar isso com transparência prejudica a imagem da empresa
É realmente bizarro que, “enquanto o exploit estava sendo executado, o próprio CodeRabbit deixou um comentário de alerta de risco no PR, quando na prática o hack estava acontecendo justamente ao executar esse PR”. Parece estranho viver num mundo em que a IA está dizendo que ela mesma está sendo hackeada. Também me preocupa mais o fato de que, embora a equipe da CodeRabbit tenha reagido rapidamente, “outros fornecedores nem responderam ao contato da investigação e continuam vulneráveis”. Palmas para a equipe da CodeRabbit, mas todos precisam agir com cuidado
Em parte da declaração oficial do CEO, ele diz que “o problema aconteceu porque o Rubocop rodava fora do sandbox”, mas sinceramente isso parece meio suspeito. Por que justamente esse componente específico funcionava de forma completamente diferente, e por que foi justamente ele que foi comprometido?
Foi um texto muito interessante, mas na verdade não é nada surpreendente. Os usuários saem adicionando um monte de apps com permissões amplas sem pensar, e o próprio sistema de permissões do GitHub também é problemático, então algo assim era inevitável. Muita gente permite de forma abusiva permissões de escrita em repositórios para apps do GitHub e até permissões de nuvem. Mesmo com proteção de branch, ainda é possível obter acesso privilegiado via GitHub Actions por meio de pull requests. Para configurar direito, é preciso ajustar o audience do GitHub OIDC, e isso nem é bem documentado. Mesmo quando se pede aos desenvolvedores dos apps que reduzam permissões e criem uma versão separada com alguns recursos desativados, a maioria nem liga ou sequer entende o problema de segurança. O GitHub precisa permitir um controle mais granular das permissões dos apps e, de forma geral, as permissões em si precisam ser mais granulares
Isso é realmente chocante. Ainda nem terminei de ler o texto, mas já é tanta coisa que dá até tontura. Na parte em que diz que um hacker poderia ter inserido malware em arquivos de distribuição de 100 mil a 1 milhão de ferramentas open source/bibliotecas/software, cheguei a pensar que o mundo poderia ter acabado. É difícil até imaginar quantos problemas parecidos ainda podem existir daqui para frente
Acho que falhas de segurança tão graves assim deveriam ser classificadas como “incidente de comprometimento” ou “evento”, com divulgação obrigatória à imprensa. Estamos falando de uma ferramenta com acesso a cerca de 7.000 clientes e 1 milhão de repositórios, comprometida por um exploit tão simples que até uma criança de 11 anos conseguiria fazer. Se era tão fácil assim hackear, é bem provável que bots, black hats ou APTs já tenham entrado e se estabelecido discretamente. Se alguém já havia invadido antes da divulgação pelos white hats, corrigir a vulnerabilidade só impede novos atacantes; talvez não elimine quem já está lá dentro. Eu sei que segurança é difícil, mas realmente precisamos acordar para isso
Um dos problemas é que vários analisadores de código, bundlers e compiladores (por exemplo, o compilador de Rust) podem executar código arbitrário sem qualquer aviso. Por exemplo, um hacker pode me mandar um repositório dizendo que é um teste de contratação, e se eu rodar
npm installou um comando de compilação Rust, meu computador pode passar imediatamente para o controle do invasor. Ou, se o PC de um colega de trabalho for invadido e um malware entrar no repositório, no fim até uma multinacional inteira pode acabar dominada por hackers estrangeiros. Quem construiu essa estrutura foram o npm e o compilador de Rust. Ferramentas assim deveriam pedir confirmação explícita sempre que executassem comandos externos (daria para armazenar em cache uma lista de permissões para não perguntar sempre). O Linux também deveria fornecer um sandbox seguro e fácil de usar para desenvolvedores; hoje você precisa construir isso manualmente. Além disso, há casos, como instalação de pacotes JS, em que nem sempre seria necessário executar código externo. E colocar segredos e configurações em variáveis de ambiente é uma péssima prática. Parece que quem criou o “12-factor app” não sabe que existem opções de linha de comando e arquivos de configuraçãorustcem sips, tudo pode aparecerGuardar em variável de ambiente a chave de permissão (private key) que permite “ser o app do GitHub que você quiser” é uma prática realmente péssima. Qualquer um pode ser hackeado, mas isso aqui é o básico do básico em gestão de segredos. A própria documentação oficial do GitHub diz claramente para não colocar private keys em variáveis de ambiente. É realmente o beabá
https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps#storing-private-keys
No momento em que li que o arquivo de configuração do Rubocop permitia especificar o caminho de arquivos Ruby de extensão, pensei: “não me diga que eles executaram extensões de usuário diretamente no ambiente de produção...”. E foi exatamente isso. Claro, bloquear só esse buraco específico não torna o sistema realmente seguro. É raro que a maioria dos linters passe por auditoria ou fuzzing contra entradas maliciosas; isso era basicamente deixar a porta aberta com uma placa de neon dizendo “por favor, me hackeie!”