flawopen.com/Teardowns/cve-2026-102437-deepseek-reasonix-git-filter-command-injection
CVE-2026-102437: inyección Git al ver diffs en Reasonix
Un par .gitattributes/.git/config manipulado puede ejecutar un filtro clean al ver un diff en Reasonix. Actualiza npm a 1.39.3 o Studio a 2.21.0.[1], [2], [3], [6], [7]
Imagina una mesa de clasificación que promete comparar solo dos etiquetas. Un paquete puede incluir una nota de ruta que ordena a la mesa ejecutar un auxiliar registrado antes de comparar el contenido. Reasonix desactivaba algunos auxiliares de Git, pero el filtro clean por archivo era una vía distinta. Cuando la pantalla de diferencias pidió a Git preparar el archivo, ese filtro podía ejecutarse con los permisos del desarrollador.[1], [3]
Conceptos Clave y Términos
Filtro clean de Git- Transformación configurada que Git puede ejecutar para convertir el contenido de un archivo del árbol de trabajo al formato almacenado en el repositorio.[1], [3]
.gitattributes- Archivo versionado del repositorio que puede asignar un filtro con nombre a determinadas rutas.[1]
.git/config- Configuración local del repositorio que puede definir qué comando ejecuta un filtro. Un clon normal no copia este archivo local.[1], [3]
Visor de diferencias- Función que pide a Git preparar y comparar el contenido actual de un archivo con el contenido confirmado.[1]
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-78
Análisis de Causa Raíz
Reasonix reforzaba las llamadas a git diff con --no-ext-diff y --no-textconv , pero esas opciones controlan mecanismos de diferencias externas y conversión de texto; no desactivan los filtros clean de contenido de Git. La vista de cambios del espacio de trabajo llamaba a git diff para una ruta seleccionada. Si el contenido del repositorio asignaba un filtro mediante .gitattributes y la configuración local de Git definía el comando de ese controlador, Git podía ejecutarlo al construir el objeto de comparación. El CVE describe un atacante local y requiere que el usuario abra la diferencia. La divulgación de GitLab indica que un clon normal no transfiere .git/config ; archivos comprimidos, carpetas sincronizadas, cachés o devcontainers preparados sí pueden incluirlo. También describe la posibilidad de que un agente local con los mismos permisos escriba configuración local en el repositorio. El impacto es la ejecución de comandos con los permisos del usuario de Reasonix, no la ejecución remota por el mero hecho de abrir un repositorio alojado en GitLab.[1], [3]
Flujo de Ataque Paso a Paso
El espacio de trabajo recibe estado de repositorio no confiable
El desarrollador abre un proyecto cuyos atributos versionados asignan un archivo a un filtro y cuya configuración Git local define ese filtro. El aviso del mantenedor requiere ambos elementos; un clon normal por sí solo no aporta la configuración local.[1], [3]
Código Fuente: Vulnerable vs. Seguro
Este constructor de argumentos es ilustrativo, no un parche listo para usar. El llamador debe enumerar todos los drivers seleccionados por .gitattributes, .git/info/attributes y los archivos de atributos globales/del sistema, y establecer discoveryComplete solo después de completar correctamente el análisis. Esta función valida los nombres recibidos y genera anulaciones de configuración en la línea de comandos; no descubre ni verifica el conjunto de drivers. La llamada vulnerable está citada en la divulgación de GitLab; el patrón defensivo es una síntesis original de la guía de los mantenedores y de sus PR de hardening fusionados.[1], [3], [4], [5]
Fragmento de origen: desktop/workspace_changes.go
// Llamada de origen citada por GitLab Threat Research; es el punto de llamada, no una función completa.
args := []string{"-C", base, "diff", "--no-ext-diff", "--no-textconv", "--relative", "HEAD", "--", filepath.FromSlash(rel)}
// Constructor ilustrativo de argumentos Go, no un parche literal del proveedor.
package gitguard
import (
"errors"
"fmt"
"path/filepath"
"regexp"
)
// El llamador debe descubrir todos los filtros seleccionados por los atributos efectivos y pasar el conjunto completo.
// Este auxiliar solo neutraliza esas claves de driver en todos los ámbitos de configuración de 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)
}
// Los nombres de subsección de Git config distinguen mayúsculas: no normalice los nombres de driver.
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 Verificación de Seguridad para Ingeniería
- ✓✓ Actualiza el paquete npm Reasonix a 1.39.3 o posterior, o Reasonix Studio a 2.21.0 o posterior, siguiendo las indicaciones actuales del proyecto.[2], [6], [7]
- ✓✓ Si una herramienta ejecuta Git en un espacio de trabajo controlado por el usuario, trata la configuración local y los atributos versionados del repositorio como datos no confiables.[1], [3]
- ✓✓ En cada llamada de Git del host que transforme contenido, identifica los filtros seleccionados por
.gitattributes,.git/info/attributesy los archivos globales o del sistema; neutraliza sus claves en las configuraciones system, global, local y worktree; falla de forma segura si la detección está incompleta.[1], [3], [4], [5] - ✓✓ Mantén
--no-ext-diffy--no-textconvcomo controles distintos; ninguno sustituye la neutralización de controladores de filtro.[1] - ✓✓ Añade pruebas de regresión con Git real que demuestren que un filtro malicioso configurado por el repositorio no se ejecuta mediante diff, status, staging, checkout ni otras operaciones de contenido admitidas por el wrapper.[4], [5]
- ✓✓ Revisa archivos comprimidos, carpetas compartidas, cachés y devcontainers en busca de
.git/configsuministrado localmente; no afirmes que un clon normal incluye ese archivo.[1], [3]
Fuentes
- 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