1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
From: Facundo Tuesca <facundo.tuesca@trailofbits.com>
Date: Tue, 5 Sep 2023 09:51:50 +0200
Subject: Fix CVE-2023-41040
This change adds a check during reference resolving to see if it
contains an up-level reference ('..'). If it does, it raises an
exception.
This fixes CVE-2023-41040, which allows an attacker to access files
outside the repository's directory.
Origin: https://github.com/gitpython-developers/GitPython/commit/64ebb9fcdfbe48d5d61141a557691fd91f1e88d6
Origin: https://github.com/gitpython-developers/GitPython/commit/65b8c6a2ccacdf26e751cd3bc3c5a7c9e5796b56
Bug: https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-cwvm-v4w8-q58c
Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2023-41040
---
git/refs/symbolic.py | 2 ++
git/test/test_refs.py | 15 +++++++++++++++
2 files changed, 17 insertions(+)
--- a/git/refs/symbolic.py
+++ b/git/refs/symbolic.py
@@ -168,6 +168,8 @@
"""Return: (str(sha), str(target_ref_path)) if available, the sha the file at
rela_path points to, or None. target_ref_path is the reference we
point to, or None"""
+ if ".." in str(ref_path):
+ raise ValueError(f"Invalid reference '{ref_path}'")
tokens: Union[None, List[str], Tuple[str, str]] = None
repodir = _git_dir(repo, ref_path)
try:
--- a/test/test_refs.py
+++ b/test/test_refs.py
@@ -5,6 +5,7 @@
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
from itertools import chain
+from pathlib import Path
from git import (
Reference,
@@ -19,9 +20,11 @@
from git.objects.tag import TagObject
from test.lib import TestBase, with_rw_repo
from git.util import Actor
+from gitdb.exc import BadName
import git.refs as refs
import os.path as osp
+import tempfile
class TestRefs(TestBase):
@@ -595,3 +598,15 @@
def test_reflog(self):
assert isinstance(self.rorepo.heads.master.log(), RefLog)
+
+ def test_refs_outside_repo(self):
+ # Create a file containing a valid reference outside the repository. Attempting
+ # to access it should raise an exception, due to it containing a parent directory
+ # reference ('..'). This tests for CVE-2023-41040.
+ git_dir = Path(self.rorepo.git_dir)
+ repo_parent_dir = git_dir.parent.parent
+ with tempfile.NamedTemporaryFile(dir=repo_parent_dir) as ref_file:
+ ref_file.write(b"91b464cd624fe22fbf54ea22b85a7e5cca507cfe")
+ ref_file.flush()
+ ref_file_name = Path(ref_file.name).name
+ self.assertRaises(BadName, self.rorepo.commit, "../../%s" % ref_file_name)
|