Thread (4 messages) flat view 4 messages, 4 authors, 2017-10-03

Security of .git/config and .git/hooks

From: Jonathan Nieder <hidden>
Date: 2017-10-02 23:45:25

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help