diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 33c3bf15b..5c293aa7b 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -168,6 +168,8 @@ def _get_ref_info_helper( """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: diff --git a/test/test_refs.py b/test/test_refs.py index 4c421767e..e7526c3b2 100644 --- 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, @@ -20,9 +21,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): @@ -616,3 +619,15 @@ def test_dereference_recursive(self): 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, f"../../{ref_file_name}")
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: