
=====================================================================

                               CERT-Renater

                     Note d'Information No. 2023/VULN290

_____________________________________________________________________

DATE                : 05/09/2023

HARDWARE PLATFORM(S): /

OPERATING SYSTEM(S): Systems running gitpython (pip) versions prior
                                         to 3.1.33.

=====================================================================
https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-wfm5-v35h-vwf4
https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-cwvm-v4w8-q58c
_____________________________________________________________________


Untrusted search path on Windows systems leading to arbitrary code
execution

High
Byron published GHSA-wfm5-v35h-vwf4 Aug 26, 2023

Package
gitpython (pip)

Affected versions
<=3.1.32

Patched versions
3.1.33


Description

Summary

When resolving a program, Python/Windows look for the current working
directory, and after that the PATH environment (see big warning in
https://docs.python.org/3/library/subprocess.html#popen-constructor).
GitPython defaults to use the git command, if a user runs GitPython
from a repo has a git.exe or git executable, that program will be
run instead of the one in the user's PATH.


Details

This is more of a problem on how Python interacts with Windows systems,
Linux and any other OS aren't affected by this. But probably people
using GitPython usually run it from the CWD of a repo.

The execution of the git command happens in

GitPython/git/cmd.py

Line 277 in 1c8310d
  git_exec_name = "git"  # default that should work on linux and windows
GitPython/git/cmd.py

Lines 983 to 996 in 1c8310d
  proc = Popen(      command,      env=env,      cwd=cwd, 
bufsize=-1,      stdin=istream or DEVNULL,      stderr=PIPE, 
stdout=stdout_sink,      shell=shell is not None and shell or 
self.USE_SHELL,      close_fds=is_posix,  # unsupported on windows 
universal_newlines=universal_newlines, 
creationflags=PROC_CREATIONFLAGS,      **subprocess_kwargs,  )
And there are other commands executed that should probably be
aware of this problem.


PoC

On a Windows system, create a git.exe or git executable in any
directory, and import or run GitPython from that directory

python -c "import git"

The git executable from the current directory will be run.
Impact

An attacker can trick a user to download a repository with a
malicious git executable, if the user runs/imports GitPython
from that directory, it allows the attacker to run any
arbitrary commands.


Possible solutions

     Default to an absolute path for the git program on Windows,
like C:\\Program Files\\Git\\cmd\\git.EXE (default git path
installation).

     Require users to set the GIT_PYTHON_GIT_EXECUTABLE
environment variable on Windows systems.
     Make this problem prominent in the documentation and
advise users to never run GitPython from an untrusted repo,
or set the GIT_PYTHON_GIT_EXECUTABLE env var to an absolute
path.

     Resolve the executable manually by only looking into the
PATH environment variable (suggested by @Byron)

Note
This vulnerability was reported via email, and it was decided
to publish it here and make it public, so the community is
aware of it, and a fix can be provided.


Severity
High

7.8/ 10


CVSS base metrics

Attack vector
Local

Attack complexity
Low

Privileges required
None

User interaction
Required

Scope
Unchanged

Confidentiality
High

Integrity
High

Availability
High

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CVE ID
CVE-2023-40590

Weaknesses
CWE-426


Credits

     @stsewd stsewd

_____________________________________________________________________


Blind local file inclusion

Moderate
Byron published GHSA-cwvm-v4w8-q58c Aug 26, 2023

Package
gitpython (pip)

Affected versions
<=3.1.33

Patched versions
None


Description

Summary

In order to resolve some git references, GitPython reads files from
the .git directory, in some places the name of the file being read is
provided by the user, GitPython doesn't check if this file is located
outside the .git directory. This allows an attacker to make GitPython
read any file from the system.


Details

This vulnerability is present in

GitPython/git/refs/symbolic.py

Lines 174 to 175 in 1c8310d
  with open(os.path.join(repodir, str(ref_path)), "rt", 
encoding="UTF-8") as fp:      value = fp.read().rstrip()
That code joins the base directory with a user given string without
checking if the final path is located outside the base directory.

I was able to exploit it from three places, but there may be more
code paths that lead to it:

GitPython/git/repo/base.py

Line 605 in 1c8310d
  def commit(self, rev: Union[str, Commit_ish, None] = None) -> Commit:
GitPython/git/repo/base.py

Line 620 in 1c8310d
  def tree(self, rev: Union[Tree_ish, str, None] = None) -> "Tree":
GitPython/git/index/base.py

Line 1353 in 1c8310d
  def diff(

PoC

Running GitPython within any repo should work, here is an
example with the GitPython repo.

import git

r = git.Repo(".")

# This will make GitPython read the README.md file from the
root of the repo
r.commit("../README.md")
r.tree("../README.md")
r.index.diff("../README.md")

# Reading /etc/random
# WARNING: this will probably halt your system, run with caution
# r.commit("../../../../../../../../../dev/random")

Impact

I wasn't able to show the contents of the files (that's why
"blind" local file inclusion), depending on how GitPython is
being used, this can be used by an attacker for something
inoffensive as checking if a file exits, or cause a DoS by
making GitPython read a big/infinite file (like /dev/random
on Linux systems).


Possible solutions

A solution would be to check that the final path isn't located
outside the repodir path (maybe even after resolving symlinks).
Maybe there could be other checks in place to make sure that
the reference names are valid.

Note
This vulnerability was reported via email, and it was decided
to publish it here and make it public, so the community is
aware of it, and a fix can be provided.


Severity
Moderate

5.3/ 10


CVSS base metrics

Attack vector
Network

Attack complexity
Low

Privileges required
None

User interaction
None

Scope
Unchanged

Confidentiality
None

Integrity
None

Availability
Low

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

CVE ID
CVE-2023-41040

Weaknesses
CWE-22


Credits

     @stsewd stsewd

=========================================================
+ CERT-RENATER        |    tel : 01-53-94-20-44         +
+ 23/25 Rue Daviel    |    fax : 01-53-94-20-41         +
+ 75013 Paris         |   email:cert@support.renater.fr +
=========================================================

