1 pontos por GN⁺ 2025-07-09 | Ainda não há comentários. | Compartilhar no WhatsApp
  • Em sistemas do tipo Unix, clonar um repositório não confiável com git clone --recursive pode permitir execução remota de código via CVE-2025-48384, exigindo atualização do Git e de softwares que incorporam Git
  • A causa é a diferença no tratamento de carriage return (\r) durante a leitura e regravação de configurações do Git, fazendo com que o valor validado e o valor realmente usado fiquem divergentes
  • Se for inserido \r no fim do path de um submódulo em .gitmodules, o caminho de checkout pode mudar para outro caminho após a validação
  • O Windows não é diretamente vulnerável porque não permite caracteres de controle em nomes de arquivo, mas o macOS é vulnerável tanto ao CVE-2024-32002 quanto ao CVE-2025-48384
  • O patch passa a colocar entre aspas os valores de configuração que contêm \r, bloqueando vetores de ataque como gravação de arquivos dentro de .git e criação de hooks do Git

Visão geral da vulnerabilidade e ação imediata

  • CVE-2025-48384 é uma vulnerabilidade do Git que pode levar à execução remota de código ao clonar um repositório não confiável com git clone --recursive em plataformas do tipo Unix
  • É necessário atualizar para as versões corrigidas do Git e também atualizar softwares que incorporam Git, incluindo o GitHub Desktop
  • Ao executar apenas git clone na linha de comando, os submódulos não são clonados automaticamente
    • Como mitigação, é possível primeiro executar git clone sem --recursive, verificar se .gitmodules é seguro e só então inicializar os submódulos
  • O GitHub Desktop faz clone com a opção recursiva por padrão, então pode ser afetado nesse comportamento

Carriage return e arquivos de configuração do Git

  • Carriage return é o caractere ASCII número 13, Carriage Return, representado como \r em strings C
  • O Unix tentou usar apenas LF, isto é, \n, para separar linhas, mas o Windows e vários protocolos da internet usam CR+LF, ou seja, \r\n
  • O formato de configuração estilo .ini do Git é usado não só em arquivos de configuração do usuário, mas também no arquivo .gitmodules incluído no repositório
  • Para dar suporte a finais de linha do DOS, o parser de configuração do Git funciona assim ao ler caracteres
    • Se o caractere atual for \r, ele verifica o próximo caractere
    • Se o próximo caractere for \n, descarta o \r e trata como quebra de linha
    • Se o próximo caractere não for \n, devolve o próximo caractere ao fluxo e retorna o próprio \r
  • Esse tratamento é aplicado linha por linha, então se alguma linha terminar com CR, esse CR pode ser removido independentemente do formato do restante do arquivo

Inconsistência entre leitura e escrita

  • O Git não apenas lê arquivos de configuração, mas também grava pares key = value ao escrever valores de configuração, como em git config
  • O código antigo só colocava o valor entre aspas duplas ao regravar a configuração nos casos abaixo
    • Quando o valor começava com espaço
    • Quando havia ; ou # dentro do valor
    • Quando o valor terminava com espaço
  • Já o código de leitura da configuração aceita strings entre aspas, então um valor escrito por write_pair podia ser relido mais tarde com o \r final removido
  • Por exemplo, se o arquivo de configuração contiver key = "foo^M", após ser regravado ele pode virar key = foo^M
    • Aqui ^M representa um caractere CR literal
  • Quando esse comportamento se combina com um valor não confiável de .gitmodules, o tratamento do caminho do submódulo fica inconsistente

Confusão no caminho do submódulo e escopo do impacto

  • Em sistemas baseados em Unix, é possível colocar caracteres de controle em nomes de arquivo, então dá para inserir um valor com CR no path de .gitmodules
  • O exemplo tem a seguinte forma
[submodule "foo"]
  path = "foo^M"
  • Se esse valor for gravado pelo código de configuração do Git em .git/modules/foo/config, ele pode ficar assim
[core]
  workdir = ../../../foo^M
  • A validação do caminho não confiável lido de .gitmodules já terá sido concluída nesse ponto
  • Depois, ao reler a configuração, o \r final é removido e o Git passa a usar um caminho diferente do que foi validado
  • Como resultado, durante a clonagem do submódulo, o local lido em path = ... pode diferir do local realmente gravado e usado
  • Esse princípio é semelhante ao do CVE-2024-32002
    • O CVE-2024-32002 confundia o Git explorando a distinção entre maiúsculas e minúsculas em submódulos
    • O CVE-2025-48384 exige um sistema de arquivos que permita caracteres de controle em nomes de arquivo
  • O Windows não é diretamente vulnerável a esse bug específico porque não permite caracteres de controle em nomes de arquivo
  • O macOS é vulnerável tanto ao CVE-2024-32002 quanto ao CVE-2025-48384

Patch e possibilidade de exploração

  • O patch altera write_pair para colocar o valor entre aspas quando ele contém \r
  • A mudança é simples: adiciona '\r' à condição que antes verificava apenas ; ou #
 	for (i = 0; value[i]; i++)
-		if (value[i] == ';' || value[i] == '#')
+		if (value[i] == ';' || value[i] == '#' || value[i] == '\r')
 			quote = "\"";
  • Com a confusão de caminhos, arquivos maliciosos do submódulo podem ser colocados em posições quase arbitrárias no sistema de arquivos e, como a validação é contornada, links simbólicos fora do repositório também podem ser seguidos
  • A forma de exploração mais direta é gravar arquivos dentro do diretório .git e criar um script de hook do Git, fazendo com que código controlado pelo atacante seja executado quando o Git rodar o hook
  • Outra possibilidade é sobrescrever .git/config
  • Um PoC ainda não foi publicado, mas foi dito que bastaria uma modificação quase trivial no exploit do CVE-2024-32002
  • Os testes do commit de correção podem dar fortes pistas sobre a forma de ataque

O problema recorrente do CR e a lição

  • Não é a primeira vez que carriage return causa problemas no Git
  • Em janeiro, RyotaK descobriu um problema no protocolo do credential helper que podia ser enganado com carriage return
  • Em 2023, André Baptista e Vítor Pinho descobriram o CVE-2023-29007, uma falha lógica no parsing de configuração
  • Essa vulnerabilidade não é um problema da linguagem C em si, mas sim um erro lógico que pode surgir em praticamente qualquer linguagem
  • O ponto em comum é que ela ocorre em comunicação entre processos entre componentes internos do Git ou entre o Git e processos externos
  • Há uma estrutura parecida com HTTP CRLF injection, request smuggling e SMTP smuggling
  • No passado, a internet dependia do princípio de robustez de Postel — “seja conservador ao enviar e liberal ao receber” —, mas talvez essa já não seja a recomendação mais sensata
  • O tema é tratado com mais detalhes no RFC 9413

Agradecimentos e correções relacionadas

Ainda não há comentários.

Ainda não há comentários.