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/cacbzzx6j6q2dun_z-pnent1u714dvnpfbrl_pieqylmczlu...@mail.gmail.com/
https://public-inbox.org/git/[email protected]/
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 protected]/
> 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