1 pontos por GN⁺ 2025-07-09 | 1 comentários | Compartilhar no WhatsApp
  • Introdução a uma técnica de ataque que usa caracteres de retorno de carro dentro de um repositório Git
  • Essa vulnerabilidade cria a possibilidade de execução remota de código (RCE)
  • Comandos maliciosos podem ser executados durante um processo específico de git clone
  • Impacto confirmado em ambientes Linux e Windows
  • Destaca os riscos de um gerenciamento inseguro de repositórios Git

Caracteres de retorno de carro e vulnerabilidade no Git

  • É possível criar, dentro de um repositório Git, nomes de arquivo que contenham caracteres de retorno de carro (\r)
  • Ao clonar com git clone um repositório que contenha esses nomes de arquivo, o processo de interpretação de comandos pode levar à execução não intencional de comandos

Cenário de execução remota de código (RCE)

  • O atacante adiciona e faz commit em um arquivo com um caractere de retorno de carro inserido no nome
  • Quando o usuário faz git clone desse repositório, uma interpretação incorreta pelo sistema de arquivos e pelos comandos do Git pode causar o risco de execução de código não desejada
  • Em especial, é possível induzir a execução automática de scripts de hook (por exemplo, código na pasta .git/hooks)

Ambientes afetados e resposta

  • Pode ocorrer no Git em vários sistemas operacionais, incluindo Linux e Windows
  • Representa uma grave ameaça de segurança para desenvolvedores e empresas que gerenciam repositórios Git ou clonam repositórios externos com frequência

Recomendações de segurança

  • Ao clonar repositórios Git externos não confiáveis, é necessário usar a versão mais recente e verificar o estado de segurança
  • É necessário detectar nomes de arquivo com caracteres incomuns no repositório, especialmente retorno de carro, e revisá-los antes do clone

1 comentários

 
GN⁺ 2025-07-09
Comentários do Hacker News
  • Como resultado de tudo isso, ao fazer um clone com submódulos, ocorre o fenômeno de ler como path = ..., mas gravar em outro caminho que não termina com ^M

    • Levanta a dúvida de como exatamente a "execução remota de código" mencionada no artigo acontece aqui, e quão grave isso é do ponto de vista de segurança

    • Embora ainda não tenham publicado um PoC, mencionam que é praticamente uma adaptação direta do exploit do CVE-2024-32002, e que o teste do commit que corrigiu isso também dá uma grande pista

    • Citação da explicação do CVE-2024-32002: ao manipular maliciosamente um repositório com submódulos e explorar um bug do Git, é possível gravar arquivos no diretório .git/ em vez da worktree do submódulo. Com isso, dá para escrever um hook que é executado imediatamente durante o clone, sem dar ao usuário sequer a chance de inspecionar o código que será de fato executado

    • Em resumo, é possível colocar um git hook malicioso no repositório; normalmente git hook não é instalado durante git clone, mas este ataque torna isso possível, abrindo a possibilidade de execução do hook durante o processo de clone

    • Mais informações sobre o novo CVE podem ser vistas aqui

      • Ao ler valores de configuração, o Git remove os caracteres CR e LF, mas ao gravar não faz escape do CR, o que causa perda na leitura posterior
      • Se o caminho do submódulo incluir um caractere CR no final, o caminho sem esse caractere passa a ser usado, permitindo que o submódulo seja feito checkout no local errado
      • Se já existir um symlink entre esse caminho truncado e o diretório de hooks do submódulo, um atacante pode executar código arbitrário por meio de um hook post-checkout
      • Além deste CVE, há muitas outras vulnerabilidades no Git, então vale a pena olhar todas em conjunto
    • Mencionam a verdade simples, porém incômoda, de que escrita arbitrária de arquivos costuma levar a RCE na maioria dos casos

  • Mencionam o risco de usar arquivos de configuração escritos em uma DSL ad-hoc

    • Muitas vezes não existe especificação formal da sintaxe, e o verdadeiro critério de parsing fica espalhado entre implementações caseiras de serialização/desserialização

    • Quando as duas partes se desencontram, por exemplo, se o parser ganhou uma sintaxe nova mas o writer não foi atualizado, essas diferenças de parsing podem virar uma bomba

    • A lição é: é preciso ter uma única source of truth, e gerar automaticamente com base nela as partes que dependem disso

    • Apontam que este bug é separado da questão de source of truth

      • É um erro de lógica puro; explicam que, se existisse uma biblioteca padrão de sistema Unix para isso, o mesmo problema poderia ter acontecido lá também
      • Se estivesse em uma biblioteca padrão dessas, o impacto seria muito mais sério; agora o dano é menor porque afeta principalmente desenvolvedores
    • Afirmam que a DSL usada aqui (formato de arquivo ini), embora seja ad-hoc, é muito comum, familiar e bem organizada, então em geral já serve como especificação prática suficiente

      • A essência do bug não está no formato, mas em um parser (ou lexer) codificado manualmente no meio do caminho, e defendem que esse tipo de código precisa parar de ser escrito
      • Ainda existem alguns lugares onde algo clever e feito à mão pode ser necessário, mas nunca em formatos de intercâmbio de dados; se precisa de ini, use toml; se não servir, JSON; até YAML serve; se quiser sofrimento de verdade, XML; e, se insistir que precisa de formato binário, protobufs
      • Em conclusão, se você não é autor de linguagem de programação, não escreva parser na mão: use uma biblioteca
  • Reproduziram o problema diretamente e o publicaram neste repositório

    • Foram imediatamente atualizar para a versão mais recente do Git, mas isso ainda não chegou ao Arch

    • Até sair um novo patch, pretendem evitar pull; como pode haver problema em repositórios famosos com pull automático, temem que a atualização leve bastante tempo

    • Levantam a dúvida se esta vulnerabilidade foi divulgada antes do patch

      • Antes, a maioria dos textos explicando o potencial de exploração de uma vulnerabilidade aparecia meses depois de ela já estar corrigida; hoje, gostariam que toda postagem deixasse claro, ainda que de passagem, a diferença entre "isso é realmente perigoso agora" e "já foi corrigido, não há com o que se preocupar"
  • Ao verem a menção de que foi feita apenas uma "modificação simples" sobre um exploit existente, questionam por que o Git não usa Landlock (um recurso de sandbox de segurança exclusivo do Linux)

    • Sugerem que a operação git clone precisaria de uma estrutura com acesso somente leitura ao diretório de config, leitura/escrita ao diretório de destino do clone e proibição de invocação de subprocessos

    • Ironizam esse momento clássico em que todo exploit sempre acaba abrindo a calculadora

    • Apontam o problema de que, se subprocessos forem proibidos, todos os git hooks, como post-checkout, deixam de funcionar

      • Explicam que, se isso não for necessário, até daria para executar o Git em um ambiente tipo contêiner com seccomp, mas muitos recursos ficariam limitados
    • E observam também que, sem subprocessos, não seria possível usar Git via SSH

  • Perguntam se o próprio Homebrew é um problema, isto é, se faz clone recursivo

    • Encontram uma possibilidade neste código

    • Comentam que o próprio objetivo do Homebrew é executar código do repositório, então seria até estranho se não houvesse clone recursivo

      • O ponto é que RCE só é relevante quando os dados clonados não deveriam ser executados, e esses casos são raros
  • Relembram com nostalgia uma famosa citação de Jon Postel sobre CR+LF

    • Compartilham este texto e avaliam que, em comparação com 2003, talvez esse conselho já não seja mais adequado hoje
    • Como Mark Crispin explicou na época, as pessoas estavam entendendo isso errado, e ligam isso ao caso em que Daniel J. Bernstein, no fim dos anos 1990, apontou problemas surgidos no processo de conversão entre humano e máquina (parsing/quoting)
    • Observam que, 25 anos depois, o problema de código de quoter que não faz escape de CR continua se repetindo e, mesmo após a correção, nem todo whitespace está sendo verificado
    • Pelo git blame, o código em questão foi escrito há 19 anos, coincidindo com o período da retrospectiva de 10 anos de Bernstein
    • Compartilham materiais adicionais como o commit relacionado e o artigo sobre qmail
    • Enfatizam, no fim, a realidade de que as lições difíceis aprendidas no século 20 precisam ser reaprendidas no século 21
  • Como o Homebrew ainda não tinha a atualização para o Git 2.50.1, parece que será preciso esperar mais um pouco

    • Sugerem tentar a atualização por esta issue ou com brew install git --HEAD
  • Compartilham que tanto o Homebrew quanto o Debian Bookworm ainda estavam distribuindo versões vulneráveis

    • Informam que agora o Homebrew já disponibiliza a versão 2.50.1
  • Refletem sobre se uma system call que lista diretórios deveria negar a existência de um arquivo caso o nome contenha caracteres de controle ASCII (bytes), tratá-lo como corrupção de disco, ou fazer outra coisa

    • Apontam a possibilidade de situações inesperadas, já que esses bytes podem ter outro significado na locale atual, e não se pode presumir, como no Windows, que todos os nomes de arquivo sejam UTF-16

    • Observam brevemente que esse problema existe porque, em sistemas do tipo Unix, nomes de arquivo (e outras strings) são apenas arrays de bytes simples