Description
This is somehow related to #1515, but as a more broad problem. Gitpython exposes some methods to interact with the git program, but gitpython fails to validate/escape the arguments (user-input), resulting in the user being able to pass options to the final git command, this doesn't seem bad, but git exposes some options (--upload-pack
and --receive-pack
) that can lead to remote code execution.
One example is the clone()
method, it receives a path
Line 1219 in 17ff263
But an option can be passed as well, leading to RCE, a full working example is:
import git
r = git.Repo.init('/tmp/test', bare=True)
r.clone("--upload-pack=touch /tmp/pwn")
A usual solution is to add --
before any user-input arguments, forcing them to always be taken as positional arguments and not options, but there are commands like git checkout that make special use of --
, git mentions the --end-of-options
option https://git-scm.com/docs/gitcli/ as an alias for --
for cases like that, but that option isn't available for git checkout
🙃
Other options could be:
- To have a list of commands (like checkout) to not add
--
- Check all command calls and add
--
manually to each one, for exampleLines 1170 to 1180 in 17ff263
that would begit.clone(multi, '--', ...)
ref #1515 (comment).