1*4882a593SmuzhiyunFrom 6ebe9231cd34dacd32a964859bc509aaa1e3f5fd Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Narpat Mali <narpat.mali@windriver.com> 3*4882a593SmuzhiyunDate: Fri, 6 Jan 2023 14:13:10 +0000 4*4882a593SmuzhiyunSubject: [PATCH] python3-git: CVE-2022-24439 fix from PR 1518 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunFix command injection 7*4882a593SmuzhiyunAdd `--` in some commands that receive user input 8*4882a593Smuzhiyunand if interpreted as options could lead to remote 9*4882a593Smuzhiyuncode execution (RCE). 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunThere may be more commands that could benefit from `--` 12*4882a593Smuzhiyunso the input is never interpreted as an option, 13*4882a593Smuzhiyunbut most of those aren't dangerous. 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunFixed commands: 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun- push 18*4882a593Smuzhiyun- pull 19*4882a593Smuzhiyun- fetch 20*4882a593Smuzhiyun- clone/clone_from and friends 21*4882a593Smuzhiyun- archive (not sure if this one can be exploited, but it doesn't hurt 22*4882a593Smuzhiyun adding `--` :)) 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunFor anyone using GitPython and exposing any of the GitPython methods to users, 25*4882a593Smuzhiyunmake sure to always validate the input (like if starts with `--`). 26*4882a593SmuzhiyunAnd for anyone allowing users to pass arbitrary options, be aware 27*4882a593Smuzhiyunthat some options may lead fo RCE, like `--exc`, `--upload-pack`, 28*4882a593Smuzhiyun`--receive-pack`, `--config` (#1516). 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunRef #1517 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunCVE: CVE-2022-24439 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunUpstream-Status: Backport [https://github.com/gitpython-developers/GitPython/pull/1518] 35*4882a593Smuzhiyun 36*4882a593SmuzhiyunSigned-off-by: Narpat Mali <narpat.mali@windriver.com> 37*4882a593Smuzhiyun--- 38*4882a593Smuzhiyun git/remote.py | 6 +++--- 39*4882a593Smuzhiyun git/repo/base.py | 4 ++-- 40*4882a593Smuzhiyun 2 files changed, 5 insertions(+), 5 deletions(-) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyundiff --git a/git/remote.py b/git/remote.py 43*4882a593Smuzhiyunindex 56f3c5b..59681bc 100644 44*4882a593Smuzhiyun--- a/git/remote.py 45*4882a593Smuzhiyun+++ b/git/remote.py 46*4882a593Smuzhiyun@@ -881,7 +881,7 @@ class Remote(LazyMixin, IterableObj): 47*4882a593Smuzhiyun else: 48*4882a593Smuzhiyun args = [refspec] 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun- proc = self.repo.git.fetch(self, *args, as_process=True, with_stdout=False, 51*4882a593Smuzhiyun+ proc = self.repo.git.fetch("--", self, *args, as_process=True, with_stdout=False, 52*4882a593Smuzhiyun universal_newlines=True, v=verbose, **kwargs) 53*4882a593Smuzhiyun res = self._get_fetch_info_from_stderr(proc, progress, 54*4882a593Smuzhiyun kill_after_timeout=kill_after_timeout) 55*4882a593Smuzhiyun@@ -905,7 +905,7 @@ class Remote(LazyMixin, IterableObj): 56*4882a593Smuzhiyun # No argument refspec, then ensure the repo's config has a fetch refspec. 57*4882a593Smuzhiyun self._assert_refspec() 58*4882a593Smuzhiyun kwargs = add_progress(kwargs, self.repo.git, progress) 59*4882a593Smuzhiyun- proc = self.repo.git.pull(self, refspec, with_stdout=False, as_process=True, 60*4882a593Smuzhiyun+ proc = self.repo.git.pull("--", self, refspec, with_stdout=False, as_process=True, 61*4882a593Smuzhiyun universal_newlines=True, v=True, **kwargs) 62*4882a593Smuzhiyun res = self._get_fetch_info_from_stderr(proc, progress, 63*4882a593Smuzhiyun kill_after_timeout=kill_after_timeout) 64*4882a593Smuzhiyun@@ -945,7 +945,7 @@ class Remote(LazyMixin, IterableObj): 65*4882a593Smuzhiyun If the operation fails completely, the length of the returned IterableList will 66*4882a593Smuzhiyun be 0.""" 67*4882a593Smuzhiyun kwargs = add_progress(kwargs, self.repo.git, progress) 68*4882a593Smuzhiyun- proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True, 69*4882a593Smuzhiyun+ proc = self.repo.git.push("--", self, refspec, porcelain=True, as_process=True, 70*4882a593Smuzhiyun universal_newlines=True, 71*4882a593Smuzhiyun kill_after_timeout=kill_after_timeout, 72*4882a593Smuzhiyun **kwargs) 73*4882a593Smuzhiyundiff --git a/git/repo/base.py b/git/repo/base.py 74*4882a593Smuzhiyunindex 7713c91..f14f929 100644 75*4882a593Smuzhiyun--- a/git/repo/base.py 76*4882a593Smuzhiyun+++ b/git/repo/base.py 77*4882a593Smuzhiyun@@ -1072,7 +1072,7 @@ class Repo(object): 78*4882a593Smuzhiyun multi = None 79*4882a593Smuzhiyun if multi_options: 80*4882a593Smuzhiyun multi = shlex.split(' '.join(multi_options)) 81*4882a593Smuzhiyun- proc = git.clone(multi, Git.polish_url(str(url)), clone_path, with_extended_output=True, as_process=True, 82*4882a593Smuzhiyun+ proc = git.clone("--", multi, Git.polish_url(str(url)), clone_path, with_extended_output=True, as_process=True, 83*4882a593Smuzhiyun v=True, universal_newlines=True, **add_progress(kwargs, git, progress)) 84*4882a593Smuzhiyun if progress: 85*4882a593Smuzhiyun handle_process_output(proc, None, to_progress_instance(progress).new_message_handler(), 86*4882a593Smuzhiyun@@ -1173,7 +1173,7 @@ class Repo(object): 87*4882a593Smuzhiyun if not isinstance(path, (tuple, list)): 88*4882a593Smuzhiyun path = [path] 89*4882a593Smuzhiyun # end assure paths is list 90*4882a593Smuzhiyun- self.git.archive(treeish, *path, **kwargs) 91*4882a593Smuzhiyun+ self.git.archive("--", treeish, *path, **kwargs) 92*4882a593Smuzhiyun return self 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun def has_separate_working_tree(self) -> bool: 95*4882a593Smuzhiyun-- 96*4882a593Smuzhiyun2.34.1 97*4882a593Smuzhiyun 98