Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2ab2ea9

Browse files
committed
safe mode to disable executing any external programs except git
1 parentbf51609 commit2ab2ea9

File tree

2 files changed

+86
-6
lines changed

2 files changed

+86
-6
lines changed

‎git/cmd.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class Git(metaclass=_GitMeta):
398398

399399
__slots__= (
400400
"_working_dir",
401+
"_safe",
401402
"cat_file_all",
402403
"cat_file_header",
403404
"_version_info",
@@ -944,17 +945,20 @@ def __del__(self) -> None:
944945
self._stream.read(bytes_left+1)
945946
# END handle incomplete read
946947

947-
def__init__(self,working_dir:Union[None,PathLike]=None)->None:
948+
def__init__(self,working_dir:Union[None,PathLike]=None,safe:bool=False)->None:
948949
"""Initialize this instance with:
949950
950951
:param working_dir:
951952
Git directory we should work in. If ``None``, we always work in the current
952953
directory as returned by :func:`os.getcwd`.
953954
This is meant to be the working tree directory if available, or the
954955
``.git`` directory in case of bare repositories.
956+
957+
TODO :param safe:
955958
"""
956959
super().__init__()
957960
self._working_dir=expand_path(working_dir)
961+
self._safe=safe
958962
self._git_options:Union[List[str],Tuple[str, ...]]= ()
959963
self._persistent_git_options:List[str]= []
960964

@@ -1205,6 +1209,43 @@ def execute(
12051209
If you add additional keyword arguments to the signature of this method, you
12061210
must update the ``execute_kwargs`` variable housed in this module.
12071211
"""
1212+
ifself._safe:
1213+
ifisinstance(command,str):
1214+
command= [command]
1215+
config_args= [
1216+
"-c",
1217+
"core.askpass=/bin/true",
1218+
"-c",
1219+
"core.fsmonitor=false",
1220+
"-c",
1221+
"core.hooksPath=/dev/null",
1222+
"-c",
1223+
"core.sshCommand=/bin/true",
1224+
"-c",
1225+
"credential.helper=/bin/true",
1226+
"-c",
1227+
"http.emptyAuth=true",
1228+
"-c",
1229+
"protocol.allow=never",
1230+
"-c",
1231+
"protocol.https.allow=always",
1232+
"-c",
1233+
"url.https://bitbucket.org/.insteadOf=git@bitbucket.org:",
1234+
"-c",
1235+
"url.https://codeberg.org/.insteadOf=git@codeberg.org:",
1236+
"-c",
1237+
"url.https://github.com/.insteadOf=git@github.com:",
1238+
"-c",
1239+
"url.https://gitlab.com/.insteadOf=git@gitlab.com:",
1240+
"-c",
1241+
"url.https://.insteadOf=git://",
1242+
"-c",
1243+
"url.https://.insteadOf=http://",
1244+
"-c",
1245+
"url.https://.insteadOf=ssh://",
1246+
]
1247+
command= [command.pop(0)]+config_args+command
1248+
12081249
# Remove password for the command if present.
12091250
redacted_command=remove_password_if_present(command)
12101251
ifself.GIT_PYTHON_TRACEand (self.GIT_PYTHON_TRACE!="full"oras_process):
@@ -1227,6 +1268,15 @@ def execute(
12271268
# just to be sure.
12281269
env["LANGUAGE"]="C"
12291270
env["LC_ALL"]="C"
1271+
# Globally disable things that can execute commands, including password prompts.
1272+
ifself._safe:
1273+
env["GIT_ASKPASS"]="/bin/true"
1274+
env["GIT_EDITOR"]="/bin/true"
1275+
env["GIT_PAGER"]="/bin/true"
1276+
env["GIT_SSH"]="/bin/true"
1277+
env["GIT_SSH_COMMAND"]="/bin/true"
1278+
env["GIT_TERMINAL_PROMPT"]="false"
1279+
env["SSH_ASKPASS"]="/bin/true"
12301280
env.update(self._environment)
12311281
ifinline_envisnotNone:
12321282
env.update(inline_env)

‎git/repo/base.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ class Repo:
131131
git_dir:PathLike
132132
"""The ``.git`` repository directory."""
133133

134+
safe:None
135+
"""Whether this is operating using restricted protocol and execution access."""
136+
134137
_common_dir:PathLike=""
135138

136139
# Precompiled regex
@@ -175,6 +178,7 @@ def __init__(
175178
odbt:Type[LooseObjectDB]=GitCmdObjectDB,
176179
search_parent_directories:bool=False,
177180
expand_vars:bool=True,
181+
safe:bool=False,
178182
)->None:
179183
R"""Create a new :class:`Repo` instance.
180184
@@ -204,6 +208,17 @@ def __init__(
204208
Please note that this was the default behaviour in older versions of
205209
GitPython, which is considered a bug though.
206210
211+
:param safe:
212+
Lock down the configuration to make it as safe as possible
213+
when working with publicly accessible, untrusted
214+
repositories. This disables all known options that can run
215+
an external program and limits networking to the HTTP
216+
protocol via https:// URLs. This might not cover Git config
217+
options that were added since this was implemented, or
218+
options that might have unknown exploit vectors. It is a
219+
best effort defense rather than an exhaustive protection
220+
measure.
221+
207222
:raise git.exc.InvalidGitRepositoryError:
208223
209224
:raise git.exc.NoSuchPathError:
@@ -235,6 +250,8 @@ def __init__(
235250
ifnotos.path.exists(epath):
236251
raiseNoSuchPathError(epath)
237252

253+
self.safe=safe
254+
238255
# Walk up the path to find the `.git` dir.
239256
curpath=epath
240257
git_dir=None
@@ -309,7 +326,7 @@ def __init__(
309326
# END working dir handling
310327

311328
self.working_dir:PathLike=self._working_tree_dirorself.common_dir
312-
self.git=self.GitCommandWrapperType(self.working_dir)
329+
self.git=self.GitCommandWrapperType(self.working_dir,safe)
313330

314331
# Special handling, in special times.
315332
rootpath=osp.join(self.common_dir,"objects")
@@ -1305,6 +1322,7 @@ def init(
13051322
mkdir:bool=True,
13061323
odbt:Type[GitCmdObjectDB]=GitCmdObjectDB,
13071324
expand_vars:bool=True,
1325+
safe:bool=False,
13081326
**kwargs:Any,
13091327
)->"Repo":
13101328
"""Initialize a git repository at the given path if specified.
@@ -1329,6 +1347,8 @@ def init(
13291347
information disclosure, allowing attackers to access the contents of
13301348
environment variables.
13311349
1350+
TODO :param safe:
1351+
13321352
:param kwargs:
13331353
Keyword arguments serving as additional options to the
13341354
:manpage:`git-init(1)` command.
@@ -1342,9 +1362,9 @@ def init(
13421362
os.makedirs(path,0o755)
13431363

13441364
# git command automatically chdir into the directory
1345-
git=cls.GitCommandWrapperType(path)
1365+
git=cls.GitCommandWrapperType(path,safe)
13461366
git.init(**kwargs)
1347-
returncls(path,odbt=odbt)
1367+
returncls(path,odbt=odbt,safe=safe)
13481368

13491369
@classmethod
13501370
def_clone(
@@ -1357,6 +1377,7 @@ def _clone(
13571377
multi_options:Optional[List[str]]=None,
13581378
allow_unsafe_protocols:bool=False,
13591379
allow_unsafe_options:bool=False,
1380+
safe:Union[bool,None]=None,
13601381
**kwargs:Any,
13611382
)->"Repo":
13621383
odbt=kwargs.pop("odbt",odb_default_type)
@@ -1418,7 +1439,11 @@ def _clone(
14181439
ifnotosp.isabs(path):
14191440
path=osp.join(git._working_dir,path)ifgit._working_dirisnotNoneelsepath
14201441

1421-
repo=cls(path,odbt=odbt)
1442+
# if safe is not explicitly defined, then the new Repo instance should inherit the safe value
1443+
ifsafeisNone:
1444+
safe=git._safe
1445+
1446+
repo=cls(path,odbt=odbt,safe=safe)
14221447

14231448
# Retain env values that were passed to _clone().
14241449
repo.git.update_environment(**git.environment())
@@ -1501,6 +1526,7 @@ def clone_from(
15011526
multi_options:Optional[List[str]]=None,
15021527
allow_unsafe_protocols:bool=False,
15031528
allow_unsafe_options:bool=False,
1529+
safe:bool=False,
15041530
**kwargs:Any,
15051531
)->"Repo":
15061532
"""Create a clone from the given URL.
@@ -1531,13 +1557,16 @@ def clone_from(
15311557
:param allow_unsafe_options:
15321558
Allow unsafe options to be used, like ``--upload-pack``.
15331559
1560+
:param safe:
1561+
TODO
1562+
15341563
:param kwargs:
15351564
See the :meth:`clone` method.
15361565
15371566
:return:
15381567
:class:`Repo` instance pointing to the cloned directory.
15391568
"""
1540-
git=cls.GitCommandWrapperType(os.getcwd())
1569+
git=cls.GitCommandWrapperType(os.getcwd(),safe)
15411570
ifenvisnotNone:
15421571
git.update_environment(**env)
15431572
returncls._clone(
@@ -1549,6 +1578,7 @@ def clone_from(
15491578
multi_options,
15501579
allow_unsafe_protocols=allow_unsafe_protocols,
15511580
allow_unsafe_options=allow_unsafe_options,
1581+
safe=safe,
15521582
**kwargs,
15531583
)
15541584

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp