Re: [PATCH 0/5] Multiple hook support
- Date: Tue, 23 Apr 2019 19:34:38 -0700
- From: Jonathan Nieder <jrnieder@xxxxxxxxx>
- Subject: Re: [PATCH 0/5] Multiple hook support
brian m. carlson wrote:
> I've talked with some people about this approach, and they've indicated
> they would prefer a configuration-based approach.
I would, too, mostly because that reduces the problem of securing
hooks to securing configuration. See
for more on this subject.
More precisely, a few problems with the current hooks system:
1. There's not a standard way to have multiple hooks for a single event.
That's what this series is about.
(The recommended workaround has been to use a trampoline script as
your hook, and to make that trampoline script implement whatever
policy for the order of invocation and accumulation of results is
appropriate, but that's a bit of a cop-out.)
2. Because they are stored in the Git repository, they do not have a
way to be automatically updated.
(The recommended workaround is to use a trampoline script as your
hook and put the actual hook somewhere standard like $PATH where
it can be upgraded system-wide. But that's a bit of a cop-out.)
3. Because they are part of the Git repository, it is very easy to
compromise a user's account by tricking them into running an
attacker-authored hook. Attacks include "hey admin, can you tell
me why 'git commit' is failing in this repo?" and "here's a zip file
containing a Git repository with our fancy software. Feel free
to look around, run 'git pull', etc".
Similar attacks, probably even worse, apply to shell prompt scripts
using commands from attacker-controlled .git/config.
(The recommended workaround is to inspect .git/config and
.git/hooks whenever you're looking at an untrusted repository, and
to write your shell prompt script defensively.)
Solving (1) without (2) feels like a bit of a missed opportunity to
me. Ideally, what I would like is
i. A central registry of trustworthy Git hooks that can be upgraded
using the system package manager to address (2). Perhaps just
git-hook-* commands on the $PATH.
ii. Instead of putting hooks in .git/hooks, put a list of hooks to
run for each event in .git/config.
iii. For backward compatibility, perform a multi-stage migration.
In the stage I am most interested in:
When encountering a hook in .git/hooks, don't run it, but print
a message about how to migrate it to the modern scheme.
To make migration to the modern scheme painless, stick a
standard trampoline script in .git/hooks in all converted and
all newly "git init"ed repositories to allow old versions of Git
to respect the configuration from (i) and (ii).
That doesn't handle core.pager et al, but those we can handle
separately (for example by, at least optionally, not respecting values
for them in per-repo config at all).
Thanks for tackling this. What do you think?