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