Vulnerability GHSA-59cr-6r3x-644w
Medium Risk
MEDIUM RISK
CVSS Score: 6.0
Score Range: 4.0–6.9
Medium severity vulnerabilities (CVSS 4.0–6.9). Important issues that meaningfully reduce security confidence.
7 hours ago
September 30, 2026 at 11:47 PM UTC
GitPython submodule update path traversal can write outside the repository
0.1.7 and 0.3.1-beta2 - 3.1.61
0.1.7 and 0.3.1-beta2 - 3.1.61
Summary
GitPython submodule update path traversal can write outside the repository
Details
Affected: GitPython 3.1.61 (latest release) and main — git/objects/submodule/base.py. git diff 3.1.61 origin/main -- git/objects/submodule/ is empty, so both are identical here.
Appendix — EVIDENCE_gitpython_path_unguarded_20260901.txt (inlined; advisories accept no attachments)
=== EVIDENCE: GitPython — the .gitmodules 'path' field reaches os.makedirs()/clone unguarded ===
Mon Aug 31 18:45:22 UTC 2026
--- artifact: tag 3.1.61 (latest release); git diff 3.1.61 origin/main -- git/objects/submodule/ is empty ---
--- the containment guard GitPython owns, and its only two call sites ---
33: _to_relative_path,
400: def _to_relative_path(cls, parent_repo: "Repo", path: PathLike) -> PathLike:
407: path = _to_relative_path(parent_repo.working_tree_dir, path)
542: path = cls._to_relative_path(repo, path)
1041: module_checkout_path = self._to_relative_path(self.repo, module_path)
--- the parent fix (_validated_name) call sites: it validates the NAME ---
309: def _validated_name(cls, name: str) -> str:
321: name = cls._validated_name(name)
541: cls._validated_name(name)
788: self._validated_name(self.name)
1040: self._validated_name(self.name)
1181: self._validated_name(self.name)
1439: self._validated_name(self.name)
1440: self._validated_name(new_name)
1489: self._validated_name(self.name)
--- update(): name validated, path not; abspath -> os.makedirs ---
try:
self._validated_name(self.name)
# ENSURE REPO IS PRESENT AND UP-TO-DATE
# END early abort if init is not allowed
checkout_module_abspath = self.abspath
module_abspath = self._module_abspath(self.repo, self.path, self.name)
# ``git submodule deinit`` leaves the repository in
# ``.git/modules`` and empties the checkout. Reconnect that retained
# repository instead of trying to clone over it.
if not dry_run and osp.isdir(module_abspath):
try:
git.Repo(module_abspath)
except InvalidGitRepositoryError:
pass
else:
if osp.lexists(checkout_module_abspath) and (
osp.islink(checkout_module_abspath)
or not osp.isdir(checkout_module_abspath)
or os.listdir(checkout_module_abspath)
):
raise OSError(
"Module directory at %r does already exist and is non-empty" % checkout_module_abspath
)
os.makedirs(checkout_module_abspath, exist_ok=True)
self._write_git_file_and_module_config(checkout_module_abspath, module_abspath)
mrepo = git.Repo(checkout_module_abspath)
--- where self.path comes from (raw .gitmodules value) ---
def _set_cache_(self, attr: str) -> None:
if attr in ("path", "_url", "_branch_path"):
reader: SectionConstraint = self.config_reader()
# Default submodule values.
try:
self.path = reader.get("path")
except cp.NoSectionError as e:
Related Vulnerabilities
Other vulnerabilities affecting the same packages
High Risk
7 hours ago
GitPython: Denial of Service via catastrophic backtracking (ReDoS) in Actor.name_email_regex — commit author/committer field parsing
0.1.7 and 0.3.1-beta2 - 3.1.59 GHSA-g5vv-9gxw-82hx
0.1.7 and 0.3.1-beta2 - 3.1.59 GHSA-g5vv-9gxw-82hx
Medium Risk
7 hours ago
GitPython: --no-index bypasses diff unsafe-option protections and enables a blind local-file content oracle
3.1.59 GHSA-whh4-5q6c-9v3x
3.1.59 GHSA-whh4-5q6c-9v3x
High Risk
7 hours ago
GitPython: Repository content can impersonate the git directory, leading to arbitrary code execution
0.1.7 and 0.3.1-beta2 - 3.1.59 GHSA-239g-whfq-7xj9
0.1.7 and 0.3.1-beta2 - 3.1.59 GHSA-239g-whfq-7xj9
Medium Risk
20 days ago
GitPython: TagReference.create positional reference bypasses kwargs-only --file guard, enabling arbitrary file read (incomplete fix of 3af0c251)
0.1.7 and 0.3.1-beta2 - 3.1.58 PYSEC-2026-3837
0.1.7 and 0.3.1-beta2 - 3.1.58 PYSEC-2026-3837
High Risk
20 days ago
GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file overwrite
0.1.7 and 0.3.1-beta2 - 3.1.57 PYSEC-2026-3838
0.1.7 and 0.3.1-beta2 - 3.1.57 PYSEC-2026-3838
Impacted packages
Timeline
Published
7 hours ago
September 30, 2026 at 11:47 PM UTC
Fixed (3.1.62)
24 days ago
September 07, 2026 at 02:57 AM UTC
Last Modified
7 hours ago
October 01, 2026 at 12:00 AM UTC