Skip to content

Commit e227e01

Browse files
authored
Merge pull request #2181 from gitpython-developers/fix-env-var-exfiltration
fix: prevent environment expansion in remote URLs
2 parents e59d9ba + 8634174 commit e227e01

4 files changed

Lines changed: 25 additions & 2 deletions

File tree

git/objects/submodule/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ def add(
608608
# END verify url
609609

610610
## See #525 for ensuring git URLs in config-files are valid under Windows.
611-
url = Git.polish_url(url)
611+
url = Git.polish_url(url, expand_vars=False)
612612

613613
# It's important to add the URL to the parent config, to let `git submodule` know.
614614
# Otherwise there is a '-' character in front of the submodule listing:

git/remote.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ def create(cls, repo: "Repo", name: str, url: str, allow_unsafe_protocols: bool
808808
"""
809809
scmd = "add"
810810
kwargs["insert_kwargs_after"] = scmd
811-
url = Git.polish_url(url)
811+
url = Git.polish_url(url, expand_vars=False)
812812
if not allow_unsafe_protocols:
813813
Git.check_unsafe_protocols(url)
814814
repo.git.remote(scmd, "--", name, url, **kwargs)

test/test_remote.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
55

66
import gc
7+
import os
78
import os.path as osp
89
from pathlib import Path
910
import random
@@ -685,6 +686,14 @@ def test_multiple_urls(self, rw_repo):
685686
# Will raise fatal: Will not delete all non-push URLs.
686687
self.assertRaises(GitCommandError, remote.delete_url, test3)
687688

689+
@with_rw_repo("HEAD", bare=False)
690+
def test_create_does_not_expand_environment_variables_in_url(self, rw_repo):
691+
url = "https://example.com/${GITPYTHON_TEST_SECRET}/repo.git"
692+
with mock.patch.dict(os.environ, {"GITPYTHON_TEST_SECRET": "sensitive-value"}):
693+
remote = rw_repo.create_remote("untrusted", url)
694+
695+
assert remote.url == url
696+
688697
def test_fetch_error(self):
689698
rem = self.rorepo.remote("origin")
690699
msg = (

test/test_submodule.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,20 @@ def test_add_no_clone_multi_options_argument(self, rwdir):
13551355
with self.assertRaises(cp.NoOptionError):
13561356
sm_config.get_value("core", "eol")
13571357

1358+
@with_rw_directory
1359+
def test_add_does_not_expand_environment_variables_in_url(self, rwdir):
1360+
parent = git.Repo.init(osp.join(rwdir, "parent"))
1361+
url = osp.join(rwdir, "${GITPYTHON_TEST_SECRET}")
1362+
source = git.Repo.init(url)
1363+
Path(source.working_tree_dir, "file").write_text("content")
1364+
source.index.add(["file"])
1365+
source.index.commit("initial")
1366+
1367+
with mock.patch.dict(os.environ, {"GITPYTHON_TEST_SECRET": "sensitive-value"}):
1368+
sm = Submodule.add(parent, "new", "new", url)
1369+
1370+
assert sm.url == Git.polish_url(url, expand_vars=False)
1371+
13581372
@with_rw_repo("HEAD")
13591373
def test_submodule_add_unsafe_url(self, rw_repo):
13601374
with tempfile.TemporaryDirectory() as tdir:

0 commit comments

Comments
 (0)