| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6991a2a commit 6b1c261
22 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,5 +33,6 @@ Contributors are: | |||
| 33 | 33 | -Steven Whitman <ninloot _at_ gmail.com> | |
| 34 | 34 | -Stefan Stancu <stefan.stancu _at_ gmail.com> | |
| 35 | 35 | -César Izurieta <cesar _at_ caih.org> | |
| 36 | + -Santos Gallegos <stsewd _at_ proton.me> | ||
| 36 | 37 | ||
| 37 | 38 | Portions derived from other open source works and are clearly marked. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,6 +5,8 @@ | |||
| 5 | 5 | # the BSD License: http://www.opensource.org/licenses/bsd-license.php | |
| 6 | 6 | ||
| 7 | 7 | import contextlib | |
| 8 | + import re | ||
| 9 | + | ||
| 8 | 10 | import io | |
| 9 | 11 | import logging | |
| 10 | 12 | import os | |
@@ -32,7 +34,7 @@ | |||
| 32 | 34 | is_posix, | |
| 33 | 35 | is_win, | |
| 34 | 36 | ) | |
| 35 | - from git.exc import CommandError | ||
| 37 | + from git.exc import CommandError, UnsafeOptionError, UnsafeProtocolError | ||
| 36 | 38 | from git.util import is_cygwin_git, cygpath, expand_path | |
| 37 | 39 | ||
| 38 | 40 | from .exc import ( | |
@@ -172,9 +174,49 @@ class Git(LazyMixin): | |||
| 172 | 174 | ||
| 173 | 175 | _excluded_ = ('cat_file_all', 'cat_file_header', '_version_info') | |
| 174 | 176 | ||
| 177 | + re_unsafe_protocol = re.compile("(.+)::.+") | ||
| 178 | + | ||
| 175 | 179 | def __getstate__(self): | |
| 176 | 180 | return slots_to_dict(self, exclude=self._excluded_) | |
| 177 | 181 | ||
| 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 | + | ||
| 178 | 220 | def __setstate__(self, d): | |
| 179 | 221 | dict_to_slots_and__excluded_are_none(self, d, excluded=self._excluded_) | |
| 180 | 222 | ||
@@ -1089,7 +1131,7 @@ def get_object_data(self, ref): | |||
| 1089 | 1131 | :note: not threadsafe""" | |
| 1090 | 1132 | hexsha, typename, size, stream = self.stream_object_data(ref) | |
| 1091 | 1133 | data = stream.read(size) | |
| 1092 | - del(stream) | ||
| 1134 | + del (stream) | ||
| 1093 | 1135 | return (hexsha, typename, size, data) | |
| 1094 | 1136 | ||
| 1095 | 1137 | def stream_object_data(self, ref): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,6 +25,14 @@ class NoSuchPathError(GitError, OSError): | |||
| 25 | 25 | """ Thrown if a path could not be access by the system. """ | |
| 26 | 26 | ||
| 27 | 27 | ||
| 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 | + | ||
| 28 | 36 | class CommandError(UnicodeMixin, GitError): | |
| 29 | 37 | """Base class for exceptions thrown at every stage of `Popen()` execution. | |
| 30 | 38 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments