flawopen.com/Teardowns/cve-2026-102437-deepseek-reasonix-git-filter-command-injection
CVE-2026-102437: injeção Git ao ver diff no Reasonix
Um par malicioso .gitattributes/.git/config pode executar um filtro clean ao abrir diff no Reasonix. Atualize npm 1.39.3 ou Studio 2.21.0.[1], [2], [3], [6], [7]
Imagine uma mesa de triagem que promete apenas comparar duas etiquetas. Um pacote pode trazer uma instrução de roteamento que manda a mesa executar um auxiliar registrado antes de comparar o conteúdo. O Reasonix desativava alguns auxiliares do Git, mas o filtro clean por arquivo era outro caminho. Quando a tela de diff pedia ao Git que preparasse o arquivo, esse filtro podia rodar com as permissões do desenvolvedor.[1], [3]
Conceitos Centrais e Termos
Filtro clean do Git- Transformação configurada que o Git pode executar para converter o conteúdo de um arquivo da árvore de trabalho para a forma armazenada no repositório.[1], [3]
.gitattributes- Arquivo versionado no repositório que pode atribuir um filtro nomeado a determinados caminhos.[1]
.git/config- Configuração local do repositório que pode definir o comando chamado por um filtro. Um clone normal não copia esse arquivo local.[1], [3]
Visualizador de diff- Recurso que pede ao Git que prepare e compare o conteúdo de trabalho de um arquivo com o conteúdo confirmado no repositório.[1]
Mapeamentos de frameworks
- Referência CWE para a fraqueza descrita neste guia: CWE-78
Análise de Causa Raiz
O Reasonix reforçava chamadas git diff com --no-ext-diff e --no-textconv , mas essas opções controlam mecanismos de diff externo e conversão de texto; elas não desativam os filtros clean de conteúdo do Git. A visualização de alterações do workspace chamava git diff para um caminho selecionado. Se o conteúdo do repositório atribuísse um filtro ao caminho via .gitattributes e a configuração local do Git definisse o comando desse driver, o Git poderia executá-lo ao construir o blob de comparação. O CVE descreve um atacante local e exige interação do usuário para abrir o diff. A divulgação do GitLab informa que um clone comum não transfere .git/config ; arquivos compactados, diretórios sincronizados, caches ou devcontainers preparados podem incluí-lo. Também descreve um agente local com as mesmas permissões que pode gravar configuração local no repositório. O impacto é execução de comandos com as permissões do usuário do Reasonix, não execução remota apenas por abrir um repositório hospedado no GitLab.[1], [3]
Fluxo de Ataque Passo a Paso
O workspace recebe estado de repositório não confiável
O desenvolvedor abre um projeto cujos atributos versionados associam um arquivo a um filtro e cuja configuração Git local define esse filtro. O aviso do mantenedor exige os dois elementos; um clone normal, sozinho, não fornece a configuração local.[1], [3]
Código-Fonte: Vulnerável vs. Seguro
Este auxiliar de argumentos é ilustrativo, não um patch pronto para uso. O chamador deve enumerar todos os drivers selecionados por .gitattributes, .git/info/attributes e arquivos de atributos globais/do sistema, definindo discoveryComplete somente após uma varredura completa bem-sucedida. Esta função valida os nomes fornecidos e gera substituições de configuração na linha de comando; ela não descobre nem verifica o conjunto de drivers. A chamada vulnerável foi citada na divulgação do GitLab; o padrão defensivo é uma síntese original das orientações dos mantenedores e dos PRs de hardening mesclados.[1], [3], [4], [5]
Trecho de origem: desktop/workspace_changes.go
// Chamada de origem citada pela GitLab Threat Research; é o ponto de chamada, não a função completa.
args := []string{"-C", base, "diff", "--no-ext-diff", "--no-textconv", "--relative", "HEAD", "--", filepath.FromSlash(rel)}
// Construtor ilustrativo de argumentos Go, não um patch literal do fornecedor.
package gitguard
import (
"errors"
"fmt"
"path/filepath"
"regexp"
)
// O chamador deve descobrir todos os filtros selecionados pelos atributos efetivos e passar o conjunto completo.
// Este auxiliar apenas neutraliza essas chaves de driver em todos os escopos de configuração do Git.
var filterDriverName = regexp.MustCompile(`^[A-Za-z0-9_-]{1,64}$`)
func hardenedDiffArgs(base, rel string, drivers []string, discoveryComplete bool) ([]string, error) {
if !discoveryComplete {
return nil, errors.New("cannot safely diff: filter-driver discovery failed")
}
args := []string{"-C", base}
seen := map[string]struct{}{}
for _, driver := range drivers {
if !filterDriverName.MatchString(driver) {
return nil, fmt.Errorf("cannot safely diff: unsupported Git filter driver name %q", driver)
}
// Os nomes das subseções do Git config diferenciam maiúsculas de minúsculas: não normalize os nomes dos drivers.
key := driver
if _, ok := seen[key]; ok {
continue
}
seen[key] = struct{}{}
for _, setting := range []string{"clean", "smudge", "process", "required"} {
args = append(args, "-c", "filter."+driver+"."+setting+"=")
}
}
return append(args, "diff", "--no-ext-diff", "--no-textconv", "--relative", "HEAD", "--", filepath.FromSlash(rel)), nil
}
Lista de Verificação de Segurança para Engenharia
- ✓✓ Atualize o pacote npm Reasonix para 1.39.3 ou posterior, ou o Reasonix Studio para 2.21.0 ou posterior, conforme a orientação atual do projeto.[2], [6], [7]
- ✓✓ Ao executar Git em um workspace controlado pelo usuário, trate a configuração local do repositório e os atributos versionados como entradas não confiáveis.[1], [3]
- ✓✓ Em cada chamada do Git do host que transforma conteúdo, identifique os filtros selecionados por
.gitattributes,.git/info/attributese arquivos de atributos globais/do sistema; neutralize suas chaves nas configurações system, global, local e worktree; falhe de forma segura se a descoberta estiver incompleta.[1], [3], [4], [5] - ✓✓ Mantenha
--no-ext-diffe--no-textconvcomo controles distintos, sem tratá-los como substitutos para neutralizar drivers de filtro.[1] - ✓✓ Inclua testes de regressão com Git real que comprovem que um filtro hostil configurado pelo repositório não é executado por diff, status, staging, checkout e outros caminhos de processamento de conteúdo suportados pelo wrapper.[4], [5]
- ✓✓ Revise fluxos com arquivos compactados, pastas compartilhadas, caches e devcontainers em busca de
.git/configfornecido localmente; não diga que um clone simples carrega esse arquivo.[1], [3]
Fontes
- GitLab Threat Research — DeepSeek-Reasonix vulnerability details and affected call site
- GitLab Advisory Database — CVE-2026-102437
- DeepSeek-Reasonix maintainer advisory — GHSA-grg2-7gc6-36m6
- DeepSeek-Reasonix Studio host Git hardening PR #11110
- DeepSeek-Reasonix 1.x host Git hardening PR #11114
- DeepSeek-Reasonix 1.39.3 release
- DeepSeek-Reasonix Studio 2.21.0 release
- MITRE CWE-78 — Improper Neutralization of Special Elements used in an OS Command