Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit61b4dda

Browse files
committed
Start on test_hook_uses_shell_not_from_cwd
This shows that run_commit_hook is vulnerable to an untrustedsearch path bug on Windows, when running script hooks: bash.exe isrun without setting NoDefaultCurrentDirectoryInExePath or otherwiseexcluding the current directory from the path search.The new test uses a non-bare repo, even though the surroundingtests use bare repos. Although the test also works if the repo isinitialized with `Repo.init(rw_dir, bare=True)`, using a bare repowould obscure how the bug this test reveals would typically beexploited, where a command that uses a hook is run after amalicious bash.exe is checked out into the working tree from anuntrusted branch.Running hooks that are themselves provided by an untrustedrepository or branch is of course never safe. If an attacker candeceive a user into doing that, then this vulnerability is notneeded. Instead, an attack that leverages this untrusted searchpath vulnerability would most likely be of roughly this form:1. The user clones a trusted repository and installs hooks.2. A malicious party offers a contribution to the project.3. The user checks out the malicious party's untrusted branch.4. The user performs an action that runs a hook.The hook the user runs is still trusted, but it runs with themalicious bash.exe found in the current directory (which is theworking tree or perhaps some subdirectory of it).The test added in this commit should, if possible, be improved tobe able to run and detect the bug (or its absence) even when bashis absent from the Windows system and, preferably, also even whenthe WSL bash.exe is present but no WSL distribution is installed.
1 parentd2506c7 commit61b4dda

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

‎test/test_index.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
# This module is part of GitPython and is released under the
44
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
55

6+
importcontextlib
67
fromioimportBytesIO
78
importlogging
89
importos
910
importos.pathasosp
1011
frompathlibimportPath
1112
importre
13+
importshutil
1214
fromstatimportS_ISLNK,ST_MODE
1315
importsubprocess
1416
importtempfile
1517

18+
importddt
1619
importpytest
1720
fromsumtypesimportconstructor,sumtype
1821

@@ -36,7 +39,7 @@
3639
fromgit.index.typimportBaseIndexEntry,IndexEntry
3740
fromgit.index.utilimportTemporaryFileSwap
3841
fromgit.objectsimportBlob
39-
fromgit.utilimportActor,hex_to_bin,rmtree
42+
fromgit.utilimportActor,cwd,hex_to_bin,rmtree
4043
fromgitdb.baseimportIStream
4144
fromtest.libimportTestBase,fixture,fixture_path,with_rw_directory,with_rw_repo
4245

@@ -172,6 +175,7 @@ def _make_hook(git_dir, name, content, make_exec=True):
172175
returnhp
173176

174177

178+
@ddt.ddt
175179
classTestIndex(TestBase):
176180
def__init__(self,*args):
177181
super().__init__(*args)
@@ -1012,6 +1016,37 @@ def test_run_commit_hook(self, rw_repo):
10121016
output=Path(rw_repo.git_dir,"output.txt").read_text(encoding="utf-8")
10131017
self.assertEqual(output,"ran fake hook\n")
10141018

1019+
# FIXME: Figure out a way to make this test also work with Absent and WslNoDistro.
1020+
@pytest.mark.xfail(
1021+
type(_win_bash_status)isWinBashStatus.WslNoDistro,
1022+
reason="Currently uses the bash.exe of WSL, even with no WSL distro installed",
1023+
raises=HookExecutionError,
1024+
)
1025+
@ddt.data((False,), (True,))
1026+
@with_rw_directory
1027+
deftest_hook_uses_shell_not_from_cwd(self,rw_dir,case):
1028+
(chdir_to_repo,)=case
1029+
1030+
repo=Repo.init(rw_dir)
1031+
_make_hook(repo.git_dir,"fake-hook","echo 'ran fake hook' >output.txt")
1032+
1033+
ifos.name=="nt":
1034+
# Copy an actual binary that is not bash.
1035+
other_exe_path=Path(os.environ["SystemRoot"],"system32","hostname.exe")
1036+
impostor_path=Path(rw_dir,"bash.exe")
1037+
shutil.copy(other_exe_path,impostor_path)
1038+
else:
1039+
# Create a shell script that doesn't do anything.
1040+
impostor_path=Path(rw_dir,"sh")
1041+
impostor_path.write_text("#!/bin/sh\n",encoding="utf-8")
1042+
os.chmod(impostor_path,0o755)
1043+
1044+
withcwd(rw_dir)ifchdir_to_repoelsecontextlib.nullcontext():
1045+
run_commit_hook("fake-hook",repo.index)
1046+
1047+
output=Path(rw_dir,"output.txt").read_text(encoding="utf-8")
1048+
self.assertEqual(output,"ran fake hook\n")
1049+
10151050
@pytest.mark.xfail(
10161051
type(_win_bash_status)isWinBashStatus.Absent,
10171052
reason="Can't run a hook on Windows without bash.exe.",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp