Skip to content

Commit

Permalink
Add a unit test for CVE-2023-40590
Browse files Browse the repository at this point in the history
This adds test_it_executes_git_not_from_cwd to verify that the
execute method does not use "git.exe" in the current directory on
Windows, nor "git" in the current directory on Unix-like systems,
when those files are executable.

It adds a _chdir helper context manager to support this, because
contextlib.chdir is only available on Python 3.11 and later.
  • Loading branch information
EliahKagan committed Aug 30, 2023
1 parent 6029211 commit 94e0fb0
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion test/test_git.py
Expand Up @@ -4,10 +4,12 @@
#
# This module is part of GitPython and is released under
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
import contextlib
import os
import shutil
import subprocess
import sys
from tempfile import TemporaryFile
from tempfile import TemporaryDirectory, TemporaryFile
from unittest import mock

from git import Git, refresh, GitCommandError, GitCommandNotFound, Repo, cmd
Expand All @@ -20,6 +22,17 @@
from git.compat import is_win


@contextlib.contextmanager
def _chdir(new_dir):
"""Context manager to temporarily change directory. Not reentrant."""
old_dir = os.getcwd()
os.chdir(new_dir)
try:
yield
finally:
os.chdir(old_dir)


class TestGit(TestBase):
@classmethod
def setUpClass(cls):
Expand Down Expand Up @@ -75,6 +88,23 @@ def test_it_transforms_kwargs_into_git_command_arguments(self):
def test_it_executes_git_to_shell_and_returns_result(self):
self.assertRegex(self.git.execute(["git", "version"]), r"^git version [\d\.]{2}.*$")

def test_it_executes_git_not_from_cwd(self):
with TemporaryDirectory() as tmpdir:
if is_win:
# Copy an actual binary executable that is not git.
other_exe_path = os.path.join(os.getenv("WINDIR"), "system32", "hostname.exe")
impostor_path = os.path.join(tmpdir, "git.exe")
shutil.copy(other_exe_path, impostor_path)
else:
# Create a shell script that doesn't do anything.
impostor_path = os.path.join(tmpdir, "git")
with open(impostor_path, mode="w", encoding="utf-8") as file:
print("#!/bin/sh", file=file)
os.chmod(impostor_path, 0o755)

with _chdir(tmpdir):
self.assertRegex(self.git.execute(["git", "version"]), r"^git version [\d\.]{2}.*$")

def test_it_accepts_stdin(self):
filename = fixture_path("cat_file_blob")
with open(filename, "r") as fh:
Expand Down

0 comments on commit 94e0fb0

Please sign in to comment.