USE_SHELL and command injection #1896
EliahKagan
announced in
Announcement
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
It has been decided to publicly disclose specific details of how an application that sets
Git.USE_SHELLtoTruecan become vulnerable, because this information is already widely known by security researchers yet may not always be obvious to application developers.The
Git.USE_SHELLclass attribute has the default value ofFalse. Setting it toTruemakes applications vulnerable to OS command injection, if untrusted text ever makes its way into any part of any argument that GitPython passes to any git command.USE_SHELLtoTrue, and it applies even to text used as paths passed to a command after--, and in other cases where it may be unintuitive.Gitobject, and implicitly through functionality provided byRepoand other classes.For this reason, setting
USE_SHELLtoTrueshould be avoided. Although theUSE_SHELLattribute is retained for backward compatibility because removing it would be a breaking change, it has been deprecated. Its docstring has been updated to warn about this, though specific details of the risks are not given there, and are instead presented below.It is likewise unsafe to pass
shell=Trueto any GitPython function that accepts it, but in the case ofUSE_SHELL, the effect is much broader, affecting all function calls whereshellcould have been passed but was not.Although
Git.USE_SHELLis available on all platforms, it is in practice unlikely to be set toTrueexcept on Windows. Setting it toTruehad at one time been recommended to work around a Windows-related bug that was fixed properly in GitPython 2.0.8. Furthermore, most GitPython functionality visibly breaks if it is set toTrueon other systems, as it is only on Windows thatsubprocess.Popenaccepts a sequence of separate arguments (rather than a single string) as a command even whenshell=True.Therefore, examples of how it can be exploited are presented here only for the Windows
cmd.exeshell. These examples are not exhaustive. WhenUSE_SHELLis set toTrue...This creates or truncates
outfile, which can be any path that the user running the application has write access to:Other redirection operators, including
<to read files and>>to append to them, can also be used.This runs the Windows calculator program (a useful choice because it is easy to observe), and can be trivially modified to run any command that can be expressed without spaces:
That spaces may induce quoting in the
Popencall that, while not intended to suppress special shell syntax, sometimes does so, is not a significant mitigation. Even if that cannot be overcome, redirection can be used to pass quoted commands to a scripting runtime, or parts of a command can be passed through as (all or part of) multiple arguments.This likewise runs the Windows calculator program or, when modified, any program:
Either the
&&and||operators can be used on dynamicGitattributes, calls toRepomethods, and elsewhere, and can be combined with arbitrary redirection.The
^character is acmd.exeescape character, as well as being syntactically significant in Git commands. This is likely to cause problems by accident, and may also aid in exploitation. An example of an accidental malfunction due to it is:This returns an empty string, even outside the rare case that the
HEADcommit makes no changes. Its effect is the same asg.diff("HEAD", "HEAD").As mentioned above, these examples not exhaustive, and there are other forms of shell syntax that can be injected.
These examples, and the risk they represent, apply only when GitPython is made to run commands through a shell, which
USE_SHELLdoes. In the absence of aTruevalue forUSE_SHELLor the optionalshellargument to functions that accept it, this risk of OS command injection is absent.Beta Was this translation helpful? Give feedback.
All reactions