Skip to content

Commit cc9a4e0

Browse files
codexByron
authored andcommitted
Block separate git directories during clone
<!-- agent --> Repo.clone() and Repo.clone_from() did not reject the clone option that redirects repository metadata to a caller-controlled path (GHSA-8mcc-hrx5-hvxc). Regression coverage exercises both keyword and multi-option input through both public clone APIs. Add the option to the existing clone denylist, matching Repo.init() and the documented allow_unsafe_options contract. Git itself registers --separate-git-dir in builtin/clone.c and verifies the redirected metadata directory in t/t5601-clone.sh. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 <codex@openai.com>
1 parent 9729ed3 commit cc9a4e0

2 files changed

Lines changed: 6 additions & 0 deletions

File tree

git/repo/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ class Repo:
159159
"-c",
160160
# Can install hooks that execute during clone:
161161
"--template",
162+
# Redirects the repository metadata to a caller-controlled path:
163+
"--separate-git-dir",
162164
# Fetches from an additional caller-controlled URI:
163165
"--bundle-uri",
164166
]

test/test_clone.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ def test_clone_unsafe_options(self, rw_repo):
133133
"-vcprotocol.ext.allow=always",
134134
f"--template={tmp_dir}",
135135
f"--bundle-uri=file://{tmp_dir}",
136+
f"--separate-git-dir={tmp_dir / 'git-dir'}",
136137
]
137138
for unsafe_option in unsafe_options:
138139
with self.assertRaises(UnsafeOptionError):
@@ -149,6 +150,7 @@ def test_clone_unsafe_options(self, rw_repo):
149150
{"c": "protocol.ext.allow=always"},
150151
{"template": tmp_dir},
151152
{"bundle_uri": f"file://{tmp_dir}"},
153+
{"separate_git_dir": tmp_dir / "git-dir"},
152154
]
153155
for unsafe_option in unsafe_options:
154156
with self.assertRaises(UnsafeOptionError):
@@ -258,6 +260,7 @@ def test_clone_from_unsafe_options(self, rw_repo):
258260
"-c protocol.ext.allow=always",
259261
"-cprotocol.ext.allow=always",
260262
"-vcprotocol.ext.allow=always",
263+
f"--separate-git-dir={tmp_dir / 'git-dir'}",
261264
]
262265
for unsafe_option in unsafe_options:
263266
with self.assertRaises(UnsafeOptionError):
@@ -270,6 +273,7 @@ def test_clone_from_unsafe_options(self, rw_repo):
270273
{"u": f"touch {tmp_file}"},
271274
{"config": "protocol.ext.allow=always"},
272275
{"c": "protocol.ext.allow=always"},
276+
{"separate_git_dir": tmp_dir / "git-dir"},
273277
]
274278
for unsafe_option in unsafe_options:
275279
with self.assertRaises(UnsafeOptionError):

0 commit comments

Comments
 (0)