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_PiEQyLmCzLUVxg@xxxxxxxxxxxxxx/ https://public-inbox.org/git/1461367997-28745-1-git-send-email-avarab@xxxxxxxxx/ 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/20171002234517.GV19555@xxxxxxxxxxxxxxxxxxxxxxxxx/ > 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