CVE
CVE-2026-42305, CVE-2026-47712
CWE
CWE-22
Sistemas afectados
- dulwich >= 0.10.0 y < 1.2.5 al clonar, obtener o hacer checkout de repositorios no confiables en Windows
- dulwich >= 0.24.0 y < 1.2.5 cuando porcelain.format_patch o dulwich format-patch procesan commits no confiables
- Herramientas Python downstream que integran Dulwich para operaciones de Git
- Servicios de CI y herramientas de escritorio que materializan repositorios o archivos de parche controlados por el atacante
Dulwich 1.2.5 es un lanzamiento de seguridad significativo para cualquier aplicación Python o herramienta interna que use Dulwich como su motor de Git. El nuevo lanzamiento corrige dos fallos distintos de manejo de nombres de ruta:
CVE-2026-42305: las rutas de clonación, obtención y checkout en Windows podían materializar entradas de árbol controladas por el atacante como archivos dentro de.gito fuera del árbol de trabajo.CVE-2026-47712:porcelain.format_patch(outdir=...)podía derivar nombres de archivo de parche a partir de asuntos de commit sin sanear y escribir fuera del directorio de salida solicitado.
En conjunto, estos fallos son un recordatorio de que las bibliotecas de Git no son solo código de análisis. Son mediadores del sistema de archivos. Cuando se permite que un nombre de árbol de Git o un asunto de commit cruce el límite de la API sin una normalización estricta, un atacante puede convertir los metadatos del repositorio en escrituras de archivos.
Paquete afectado
Paquete de PyPI afectado:
dulwich>= 0.10.0, < 1.2.5para el problema de checkout en Windows (CVE-2026-42305)dulwich>= 0.24.0, < 1.2.5para el problema de traversal deformat_patch(CVE-2026-47712)
Lanzamiento parcheado:
dulwich1.2.5
Los patrones de uso afectados incluyen:
porcelain.clone- flujos de obtención o checkout de repositorios construidos sobre Dulwich
- la CLI de
dulwichen Windows porcelain.format_patch- cualquier servicio que formatea parches a partir de repositorios no confiables, pull requests u objetos de commit importados
CVE-2026-42305: el manejo de rutas en Windows permitía que las entradas de árbol se convirtieran en escrituras
El problema de mayor severidad es CVE-2026-42305. Upstream lo describe como escritura de archivos arbitraria que conduce a ejecución remota de código al clonar o hacer checkout de un repositorio malicioso en Windows.
La causa raíz es que Dulwich aceptaba nombres de entrada de árbol que contenían bytes inofensivos como nombres de archivo literales en POSIX pero estructurales en Windows:
.git\hooks\pre-commit.exe
..\outside.txt
.git::$INDEX_ALLOCATION
git~2
Cada uno de esos nombres corresponde a un peligro distinto específico de Windows:
\se convierte en un separador de ruta real en Windows, así que una sola entrada de árbol puede materializar directorios o archivos anidados.:invoca el comportamiento de flujos de datos alternativos (ADS) de NTFS.git~<dígitos>puede resolverse al alias de nombre corto de.git.
Eso convierte un repositorio controlado por el atacante en una primitiva de escritura. El ejemplo más directo del aviso es el más importante:
.git\hooks\pre-commit.exe
En POSIX esto es solo un nombre de archivo que contiene un byte de barra invertida. En Windows se convierte en un archivo plantado bajo .git/hooks/. Git para Windows ejecutará ese hook en el siguiente git commit, por lo que el aviso trata esto como una ruta hacia la ejecución de código en el contexto del usuario víctima.
La misma clase también permite el escape del árbol de trabajo:
..\outside.txt
Si el código de checkout trata la entrada como un elemento de ruta normal, Windows no lo hará.
La barrera de configuración se leyó mal
El fallo se agravó por un error de configuración. El código previo a la corrección usaba el nombre de opción equivocado al leer el interruptor de protección de NTFS:
if config.get_boolean(b"core", b"core.protectNTFS", os.name == "nt"):
validate_path_element = validate_path_element_ntfs
Esa no es la clave documentada. El código corregido pasa al nombre de opción correcto y cambia el valor predeterminado a True en todas las plataformas:
if config.get_boolean(b"core", b"protectNTFS", True):
validate_path_element = validate_path_element_ntfs
Ese cambio importa incluso en POSIX. Un repositorio creado o replicado en Linux todavía puede clonarse después en Windows, así que rechazar nombres hostiles para NTFS solo en Windows no es suficiente.
Qué cambia la 1.2.5 en la validación de rutas
El parche 1.2.5 también refuerza el validador real. Los metadatos del commit upstream muestran las nuevas comprobaciones añadidas a validate_path_element_ntfs:
if b"\\" in element:
return False
if b":" in element:
return False
if _is_ntfs_dotgit_short_name(normalized):
return False
if _is_reserved_windows_device_name(normalized):
return False
Esas comprobaciones cierran varias clases a la vez:
- división de rutas basada en barra invertida
- abuso de flujos de datos alternativos como
.git::$INDEX_ALLOCATION - alias de nombre corto
git~<dígitos>de.git - nombres de dispositivo reservados como
NUL,AUX,COM1yLPT1
Esta es una corrección quirúrgica con un objetivo claro: tratar los nombres de árbol del repositorio como entrada hostil del sistema de archivos, no como bytes opacos.
CVE-2026-47712: format_patch confiaba en el asunto del commit como componente de ruta
El segundo problema es de menor severidad pero sigue siendo relevante para la automatización que maneja commits no confiables. Antes de la 1.2.5, dulwich.patch.get_summary() solo sustituía los espacios por guiones:
def get_summary(commit):
decoded = commit.message.decode(errors="replace")
lines = decoded.splitlines()
return lines[0].replace(" ", "-") if lines else ""
Ese resumen luego se incrustaba en:
os.path.join(outdir, f"{i:04d}-{summary}.patch")
Como el código no eliminaba /, \, .. ni :, un asunto de commit malicioso podía dirigir la escritura del parche fuera de outdir.
Ejemplos reducidos del aviso:
x/../../x -> <outdir>/0001-x/../../x.patch
x\..\..\x -> ruta de escape en Windows
a:b -> comportamiento de nombre de archivo inválido o especial en Windows
Esto importa en cualquier lugar donde un servicio o automatización local ejecute format_patch sobre repositorios no confiables, como exportadores de parches, puentes de revisión de código, pipelines de importación o trabajos de análisis de repositorios que persisten artefactos de parche en disco.
Cómo funciona la corrección de format_patch
El commit upstream c2446e51b añade un sanitizador dedicado que refleja el propio comportamiento format_sanitized_subject de Git:
def _sanitize_subject_for_filename(text: str, max_length: int = 52) -> str:
# mantiene solo [A-Za-z0-9._]
# colapsa otras secuencias a "-"
# colapsa "." repetidos
return "".join(result)[:max_length].rstrip(".-")
get_summary() ahora llama a ese sanitizador en lugar de hacer un único replace(" ", "-").
Eso corrige tres problemas operativos a la vez:
- path traversal mediante separadores o
.. - caracteres hostiles para Windows como
: - nombres de archivo patológicamente largos que exceden las expectativas normales del sistema de archivos
La lección de diseño importante es la misma que aparece en extractores de archivos comprimidos y gestores de paquetes: “suficientemente seguro para mostrar” no es lo mismo que “seguro para incrustar en una ruta del sistema de archivos”.
Detección y delimitación
Primero, inventaría la versión instalada:
python3 -c "import dulwich; print(dulwich.__version__)"
pip show dulwich
Luego localiza las rutas de código que importan en tu entorno:
rg -n "porcelain\\.clone|porcelain\\.format_patch|format-patch" .
Trata estos casos como máxima prioridad:
- herramientas de desarrollo en Windows o trabajos de CI que clonan o hacen checkout de repositorios no confiables con Dulwich
- servicios que aceptan URLs de repositorio u objetos Git de usuarios y los materializan con Dulwich
- automatización que escribe archivos de parche en disco a partir de commits controlados por el atacante o de terceros
Para CVE-2026-42305, revisa si algún host Windows procesó repositorios no confiables mientras ejecutaba versiones afectadas. Para CVE-2026-47712, revisa cualquier servicio que llame a porcelain.format_patch con historial de commits controlado por el usuario.
Remediación
Actualiza al lanzamiento corregido:
pip install --upgrade "dulwich>=1.2.5"
Si empaquetas dependencias mediante lockfiles o artefactos vendorizados, asegúrate de que la versión corregida sea la que realmente resuelve el runtime.
La guía temporal difiere según el problema:
- Para
CVE-2026-42305, upstream dice que no hay una solución alternativa previa al parche efectiva porque la configuración documentadacore.protectNTFSse estaba leyendo incorrectamente. - Para
CVE-2026-47712, puedes reducir el riesgo usandostdout=True, elegiendo tú mismo la ruta de destino, y rechazando rutas resueltas que escapen del directorio de salida previsto.
Si no puedes parchear de inmediato, el control temporal más seguro es evitar usar compilaciones vulnerables de Dulwich sobre repositorios no confiables, especialmente en Windows.
Por qué este lanzamiento merece atención
Muchos equipos tratan las bibliotecas de Git como plomería, pero Dulwich se sitúa directamente en un límite de confianza entre datos de repositorio controlados por el atacante y escrituras al sistema de archivos local. La 1.2.5 corrige dos casos separados donde los metadatos cruzaron ese límite con una normalización insuficiente.
Para los equipos de AppSec, la conclusión es sencilla: si tu herramienta Python clona repositorios, hace checkout de árboles de trabajo o genera archivos de parche a partir de entradas no confiables, Dulwich no es solo una dependencia para actualizar eventualmente. Es una dependencia cuyas reglas de mediación del sistema de archivos necesitan ser correctas ahora mismo.
De la investigación a la remediación
Comprueba si este patrón existe en tu código
Convierte esta investigación en un flujo de remediación. Analiza dependencias y manifiestos para detectar riesgos similares en la cadena de suministro y prioriza las correcciones con contexto de alcanzabilidad.