Thread (1 message) 1 message, 1 author, 2017-10-03

Re: Security of .git/config and .git/hooks

From: Junio C Hamano <hidden>
Date: 2017-10-03 01:12:25

Jonathan Nieder [off-list ref] writes:
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.
The list of "safe" things are configurable by having something in
~/.gitconfig, perhaps?

How would this work, from the end-user's point of view, with "git
config --global" and "git config --local"?
 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.
Meaning, "include" is not in "safe" category, but a value that
begins with "~/.config/git/" are excempt???
 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.
I am not sure what this means.  .git/hooks/pre-commit being a
symbolic link to "~/.config/git/hooks/pre-commit-fancy"
(i.e. readlink gives the path with tilde unexpanded), so that the
attacked sysadmin will not run it from ~attacker/.config/git/hooks?  

And the code that finds a hook to run sees .git/hooks/pre-commit,
resolves the symlink manually and makes sure it leads to somewhere
inside ~/.config/...  (otherwise it rejects) and then uses the
pointed-at copy?

At that point, we are not taking any advantage of symbolic-link-ness
of the entity, so .git/hooks/pre-commit being a text file that has a
single like, e.g.

	# safe-hook: pre-commit-fancy

may be sufficient (and we do not have to worry about systems without
symbolic links)?  The machinery that used to manually resolved symlink
instead reads it, finds "pre-commit-fancy" in ~/.config/git/hooks/
and runs it, and you get the same behaviour, no?
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).
I guess I invented 3d. without reading ahead X-<.  None of the 3x
variants other than 3 proper will not work for scripts and existing
code that sees that .git/hooks/pre-commit is an executable and runs
it, and 3 proper will not work without symbolic links, so this means
we'd need "git locate-hook pre-commit" (and underlying locate_hook()
helper API) that returns "/home/me/.git/config/hook/pre-commit-fancy"
or fails when we do this transition.  In an unconverted repository,
it may return $PWD/.git/hooks/pre-commit, or failure if we are
running under the paranoid mode.

Sounds workable.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help