@@ -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            if  not  os .path .exists (epath ):
236251                raise  NoSuchPathError (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_dir  or  self .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-         return  cls (path , odbt = odbt )
1367+         return  cls (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        if  not  osp .isabs (path ):
14191440            path  =  osp .join (git ._working_dir , path ) if  git ._working_dir  is  not None  else  path 
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+         if  safe  is  None :
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        if  env  is  not None :
15421571            git .update_environment (** env )
15431572        return  cls ._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