Subject: Re: [PATCH 0/5] Multiple hook support

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Wed, 24 Apr 2019 09:43:46 +0200

On Wed, Apr 24 2019, Jonathan Nieder wrote:

> brian m. carlson wrote:

brian: I'm very interested in this. I barked up this tree before almost
exactly 3 years ago:

    https://public-inbox.org/git/[email-masked]/
    https://public-inbox.org/git/[email-masked]/

If you haven't seen those threads you might find them interesting. In
particular there's a previous discussion about the "exit on first fail"
v.s. "run them all" semantics. I'll elaborate elsewhere in this thread.

The only bit that landed from that was 867ad08a26 ("hooks: allow
customizing where the hook directory is", 2016-05-04), which, in reply
to JN below...:

>> 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
> https://public-inbox.org/git/[email-masked]/
> 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.)

You can accomplish this with core.hooksPath, and presumably a
combination of core.hooksPath and brian's patches here. That was my
two-step plan in 2016, but I obviously never got to step #2.

So in /etc/gitconfig on your server you set core.hooksPath=/etc/githooks
and then your pre-receive hook will be /etc/githooks/pre-receive, or
/etc/githooks/pre-receive.d/*.

>  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?
>
> Thanks,
> Jonathan