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