Security of .git/config and .git/hooks
- From
Jonathan Nieder <jrnieder@gmail.com>
- Date
- Oct 2, 2017, 23:45 UTC
- Message-ID
- <20171002234517.GV19555@aiede.mtv.corp.google.com>
Hi,
This topic has been mentioned on this mailing list before but I had trouble finding a relevant reference. Links welcome.
Suppose that I add the following to .git/config in a repository on a shared computer:
[pager] log = rm -fr / fsck = rm -fr /
("rm -fr /" is of course a placeholder here.)I then tell a sysadmin that git commands are producing strange output and I am having trouble understanding what is going on. They may run "git fsck" or "git log"; in either case, the output is passed to the pager I configured, allowing me to run an arbitrary command using the sysadmin's credentials.
You might say that this is the sysadmin's fault, that they should have read through .git/config before running any Git commands. But I don't find it so easy to blame them.
A few related cases that might not seem so dated:
1. I put my repository in a zip file and ask a Git expert to help me
recover data from it, or 2. My repository is in a shared directory on NFS. Unless the
administrator setting that up is very careful, it is likely that
the least privileged user with write access to .git/config or
.git/hooks/ may be someone that I don't want to be able to run
arbitrary commands on behalf of the most privileged user working
in that repository.A similar case to compare to is Linux's "perf" tool, which used to respect a .perfconfig file from the current working directory. Fortunately, nowadays "perf" only respects ~/.perfconfig and /etc/perfconfig.
Proposed fix: because of case (1), I would like a way to tell Git to stop trusting any files in .git. That is:
1. Introduce a (configurable) list of "safe" configuration items that
can be set in .git/config and don't respect any others. 2. But what if I want to set a different pager per-repository?
I think we could do this using configuration "profiles".
My ~/.config/git/profiles/ directory would contain git-style
config files for repositories to include. Repositories could
then contain[include] path = ~/.config/git/profiles/fancy-log-pager
to make use of those settings. The facility (1) would
special-case this directory to allow it to set "unsafe" settings
since files there are assumed not to be under the control of an
attacker. 3. Likewise for hooks: my ~/.config/git/hooks/ directory would
contain hooks for repositories to make use of. Repositories could
symlink to hook files from there to make use of them. That would allow the configured hooks in ~/.config/git/hooks/ to
be easy to find and to upgrade in one place. To help users migrate, when a hook is present and executable in
.git/hooks/, Git would print instructions for moving it to
~/.config/git/hooks/ and replacing it with a symlink after
inspecting it.For backward compatibility, this facility would be controlled by a global configuration setting. If that setting is not enabled, then the current, less safe behavior would remain.
One downside of (3) is its reliance on symlinks. Some alternatives:
3b. Use core.hooksPath configuration instead. Rely on (2).
3c. Introduce new hook.* configuration to be used instead of hook
scripts. Rely on (2).Thoughts? Jonathan