Skip to content

Commit 6b1c261

Browse files
committed
CVE-2022-24439 Hand Cherry-Pick GitPython/pull/1521
More unfinished changes Unfinished changes Unfinished changes All code changes should be in, time to test them Fix things Tox didn't like for Python3 Fix more errors found during testing Try to fix DDT problem with Python2
1 parent 6991a2a commit 6b1c261

22 files changed

+2478
-817
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ Contributors are:
3333
-Steven Whitman <ninloot _at_ gmail.com>
3434
-Stefan Stancu <stefan.stancu _at_ gmail.com>
3535
-César Izurieta <cesar _at_ caih.org>
36+
-Santos Gallegos <stsewd _at_ proton.me>
3637

3738
Portions derived from other open source works and are clearly marked.

errortext.txt

+329
Large diffs are not rendered by default.

git/cmd.py

+44-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66

77
import contextlib
8+
import re
9+
810
import io
911
import logging
1012
import os
@@ -32,7 +34,7 @@
3234
is_posix,
3335
is_win,
3436
)
35-
from git.exc import CommandError
37+
from git.exc import CommandError, UnsafeOptionError, UnsafeProtocolError
3638
from git.util import is_cygwin_git, cygpath, expand_path
3739

3840
from .exc import (
@@ -172,9 +174,49 @@ class Git(LazyMixin):
172174

173175
_excluded_ = ('cat_file_all', 'cat_file_header', '_version_info')
174176

177+
re_unsafe_protocol = re.compile("(.+)::.+")
178+
175179
def __getstate__(self):
176180
return slots_to_dict(self, exclude=self._excluded_)
177181

182+
@classmethod
183+
def check_unsafe_protocols(cls, url):
184+
"""
185+
Check for unsafe protocols.
186+
Apart from the usual protocols (http, git, ssh),
187+
Git allows "remote helpers" that have the form `<transport>::<address>`,
188+
one of these helpers (`ext::`) can be used to invoke any arbitrary command.
189+
See:
190+
- https://git-scm.com/docs/gitremote-helpers
191+
- https://git-scm.com/docs/git-remote-ext
192+
"""
193+
match = cls.re_unsafe_protocol.match(url)
194+
if match:
195+
protocol = match.group(1)
196+
raise UnsafeProtocolError(
197+
"The `" + protocol + "::` protocol looks suspicious, use `allow_unsafe_protocols=True` to allow it."
198+
)
199+
200+
@classmethod
201+
def check_unsafe_options(cls, options, unsafe_options):
202+
"""
203+
Check for unsafe options.
204+
Some options that are passed to `git <command>` can be used to execute
205+
arbitrary commands, this are blocked by default.
206+
"""
207+
# Options can be of the form `foo` or `--foo bar` `--foo=bar`,
208+
# so we need to check if they start with "--foo" or if they are equal to "foo".
209+
bare_unsafe_options = [
210+
option.lstrip("-")
211+
for option in unsafe_options
212+
]
213+
for option in options:
214+
for unsafe_option, bare_option in zip(unsafe_options, bare_unsafe_options):
215+
if option.startswith(unsafe_option) or option == bare_option:
216+
raise UnsafeOptionError(
217+
unsafe_option +" is not allowed, use `allow_unsafe_options=True` to allow it."
218+
)
219+
178220
def __setstate__(self, d):
179221
dict_to_slots_and__excluded_are_none(self, d, excluded=self._excluded_)
180222

@@ -1089,7 +1131,7 @@ def get_object_data(self, ref):
10891131
:note: not threadsafe"""
10901132
hexsha, typename, size, stream = self.stream_object_data(ref)
10911133
data = stream.read(size)
1092-
del(stream)
1134+
del (stream)
10931135
return (hexsha, typename, size, data)
10941136

10951137
def stream_object_data(self, ref):

git/exc.py

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class NoSuchPathError(GitError, OSError):
2525
""" Thrown if a path could not be access by the system. """
2626

2727

28+
class UnsafeProtocolError(GitError):
29+
"""Thrown if unsafe protocols are passed without being explicitly allowed."""
30+
31+
32+
class UnsafeOptionError(GitError):
33+
"""Thrown if unsafe options are passed without being explicitly allowed."""
34+
35+
2836
class CommandError(UnicodeMixin, GitError):
2937
"""Base class for exceptions thrown at every stage of `Popen()` execution.
3038

0 commit comments

Comments
 (0)