From 54709d9efd4624745ed0f67029ca30ee2ca87bc9 Mon Sep 17 00:00:00 2001 From: Dylan Katz Date: Mon, 21 Aug 2017 11:14:37 -0600 Subject: [PATCH 1/2] Fix leaking environment variables --- git/repo/base.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index 28bb2a5d7..1dfe91840 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -9,6 +9,7 @@ import os import re import sys +import warnings from git.cmd import ( Git, @@ -50,8 +51,11 @@ __all__ = ('Repo',) -def _expand_path(p): - return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p)))) +def _expand_path(p, unsafe=True): + if unsafe: + return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p)))) + else: + return osp.normpath(osp.abspath(osp.expanduser(p))) class Repo(object): @@ -90,7 +94,7 @@ class Repo(object): # Subclasses may easily bring in their own custom types by placing a constructor or type here GitCommandWrapperType = Git - def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False): + def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, unsafe=True): """Create a new Repo instance :param path: @@ -121,7 +125,10 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals epath = os.getcwd() if Git.is_cygwin(): epath = decygpath(epath) - epath = _expand_path(epath or path or os.getcwd()) + if unsafe and ("%" in epath or "$" in epath): + warnings.warn("The use of environment variables in paths is deprecated" + + "\nfor security reasons and may be removed in the future!!") + epath = _expand_path(epath or path or os.getcwd(), unsafe) if not os.path.exists(epath): raise NoSuchPathError(epath) @@ -148,7 +155,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals sm_gitpath = find_worktree_git_dir(dotgit) if sm_gitpath is not None: - self.git_dir = _expand_path(sm_gitpath) + self.git_dir = _expand_path(sm_gitpath, unsafe) self._working_tree_dir = curpath break @@ -862,12 +869,17 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): the directory containing the database objects, i.e. .git/objects. It will be used to access all object data + :param unsafe: + if specified, environment variables will not be escaped. This + can lead to information disclosure, allowing attackers to + access the contents of environment variables + :parm kwargs: keyword arguments serving as additional options to the git-init command :return: ``git.Repo`` (the newly created repo)""" if path: - path = _expand_path(path) + path = _expand_path(path, unsafe) if mkdir and path and not osp.exists(path): os.makedirs(path, 0o755) From 67291f0ab9b8aa24f7eb6032091c29106de818ab Mon Sep 17 00:00:00 2001 From: Dylan Katz Date: Mon, 21 Aug 2017 12:09:37 -0600 Subject: [PATCH 2/2] Fixed missing parameter and changed name --- git/repo/base.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index 1dfe91840..d575466db 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -51,11 +51,11 @@ __all__ = ('Repo',) -def _expand_path(p, unsafe=True): - if unsafe: - return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p)))) - else: - return osp.normpath(osp.abspath(osp.expanduser(p))) +def _expand_path(p, expand_vars=True): + p = osp.expanduser(p) + if expand_vars: + p = osp.expandvars(p) + return osp.normpath(osp.abspath(p)) class Repo(object): @@ -94,7 +94,7 @@ class Repo(object): # Subclasses may easily bring in their own custom types by placing a constructor or type here GitCommandWrapperType = Git - def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, unsafe=True): + def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, expand_vars=True): """Create a new Repo instance :param path: @@ -120,15 +120,17 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ + epath = path or os.getenv('GIT_DIR') if not epath: epath = os.getcwd() if Git.is_cygwin(): epath = decygpath(epath) - if unsafe and ("%" in epath or "$" in epath): - warnings.warn("The use of environment variables in paths is deprecated" - + "\nfor security reasons and may be removed in the future!!") - epath = _expand_path(epath or path or os.getcwd(), unsafe) + epath = epath or path or os.getcwd() + if expand_vars and ("%" in epath or "$" in epath): + warnings.warn("The use of environment variables in paths is deprecated" + + "\nfor security reasons and may be removed in the future!!") + epath = _expand_path(epath, expand_vars) if not os.path.exists(epath): raise NoSuchPathError(epath) @@ -155,7 +157,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals sm_gitpath = find_worktree_git_dir(dotgit) if sm_gitpath is not None: - self.git_dir = _expand_path(sm_gitpath, unsafe) + self.git_dir = _expand_path(sm_gitpath, expand_vars) self._working_tree_dir = curpath break @@ -851,7 +853,7 @@ def blame(self, rev, file, incremental=False, **kwargs): return blames @classmethod - def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): + def init(cls, path=None, mkdir=True, odbt=DefaultDBType, expand_vars=True, **kwargs): """Initialize a git repository at the given path if specified :param path: @@ -869,7 +871,7 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): the directory containing the database objects, i.e. .git/objects. It will be used to access all object data - :param unsafe: + :param expand_vars: if specified, environment variables will not be escaped. This can lead to information disclosure, allowing attackers to access the contents of environment variables @@ -879,7 +881,7 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): :return: ``git.Repo`` (the newly created repo)""" if path: - path = _expand_path(path, unsafe) + path = _expand_path(path, expand_vars) if mkdir and path and not osp.exists(path): os.makedirs(path, 0o755)