mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-23 06:55:25 -05:00
When an attacker can convince a user to clone a crafted repository
that contains an embedded bare repository with malicious hooks, any Git
command the user runs after entering that subdirectory will discover
the bare repository and execute the hooks. The user does not even need
to run a Git command explicitly: many shell prompts run `git status`
in the background to display branch and dirty state information, and
`git status` in turn may invoke the fsmonitor hook if so configured,
making the user vulnerable the moment they `cd` into the directory. The
`safe.bareRepository` configuration variable (introduced in 8959555cee
(setup_git_directory(): add an owner check for the top-level directory,
2022-03-02)) already provides protection against this attack vector by
allowing users to set it to "explicit", but the default remained "all"
for backwards compatibility.
Since Git 3.0 is the natural point to change defaults to safer
values, flip the default from "all" to "explicit" when built with
`WITH_BREAKING_CHANGES`. This means Git will refuse to work with bare
repositories that are discovered implicitly by walking up the directory
tree. Bare repositories specified via `--git-dir` or `GIT_DIR` continue
to work, and directories that look like `.git`, worktrees, or submodule
directories are unaffected (the existing `is_implicit_bare_repo()`
whitelist handles those cases).
Users who rely on implicit bare repository discovery can restore the
previous behavior by setting `safe.bareRepository=all` in their global
or system configuration.
The test for the "safe.bareRepository in the repository" scenario
needed a more involved fix: it writes a `safe.bareRepository=all`
entry into the bare repository's own config to verify that repo-local
config does not override the protected (global) setting. Previously,
`test_config -C` was used to write that entry, but its cleanup runs `git
-C <bare-repo> config --unset`, which itself fails when the default is
"explicit" and the global config has already been cleaned up. Switching
to direct git config --file access avoids going through repository
discovery entirely.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
69 lines
3.3 KiB
Plaintext
69 lines
3.3 KiB
Plaintext
safe.bareRepository::
|
|
Specifies which bare repositories Git will work with. The currently
|
|
supported values are:
|
|
+
|
|
* `all`: Git works with all bare repositories. This is the default in
|
|
Git 2.x.
|
|
* `explicit`: Git only works with bare repositories specified via
|
|
the top-level `--git-dir` command-line option, or the `GIT_DIR`
|
|
environment variable (see linkgit:git[1]). This will be the default
|
|
in Git 3.0.
|
|
+
|
|
If you do not use bare repositories in your workflow, then it may be
|
|
beneficial to set `safe.bareRepository` to `explicit` in your global
|
|
config. This will protect you from attacks that involve cloning a
|
|
repository that contains a bare repository and running a Git command
|
|
within that directory.
|
|
+
|
|
If you use bare repositories regularly and want to preserve the current
|
|
behavior after upgrading to Git 3.0, set `safe.bareRepository` to `all`
|
|
in your global or system config.
|
|
+
|
|
This config setting is only respected in protected configuration (see
|
|
<<SCOPES>>). This prevents untrusted repositories from tampering with
|
|
this value.
|
|
|
|
safe.directory::
|
|
These config entries specify Git-tracked directories that are
|
|
considered safe even if they are owned by someone other than the
|
|
current user. By default, Git will refuse to even parse a Git
|
|
config of a repository owned by someone else, let alone run its
|
|
hooks, and this config setting allows users to specify exceptions,
|
|
e.g. for intentionally shared repositories (see the `--shared`
|
|
option in linkgit:git-init[1]).
|
|
+
|
|
This is a multi-valued setting, i.e. you can add more than one directory
|
|
via `git config --add`. To reset the list of safe directories (e.g. to
|
|
override any such directories specified in the system config), add a
|
|
`safe.directory` entry with an empty value.
|
|
+
|
|
This config setting is only respected in protected configuration (see
|
|
<<SCOPES>>). This prevents untrusted repositories from tampering with this
|
|
value.
|
|
+
|
|
The value of this setting is interpolated, i.e. `~/<path>` expands to a
|
|
path relative to the home directory and `%(prefix)/<path>` expands to a
|
|
path relative to Git's (runtime) prefix.
|
|
+
|
|
To completely opt-out of this security check, set `safe.directory` to the
|
|
string `*`. This will allow all repositories to be treated as if their
|
|
directory was listed in the `safe.directory` list. If `safe.directory=*`
|
|
is set in system config and you want to re-enable this protection, then
|
|
initialize your list with an empty value before listing the repositories
|
|
that you deem safe. Giving a directory with `/*` appended to it will
|
|
allow access to all repositories under the named directory.
|
|
+
|
|
As explained, Git only allows you to access repositories owned by
|
|
yourself, i.e. the user who is running Git, by default. When Git
|
|
is running as 'root' in a non Windows platform that provides sudo,
|
|
however, git checks the SUDO_UID environment variable that sudo creates
|
|
and will allow access to the uid recorded as its value in addition to
|
|
the id from 'root'.
|
|
This is to make it easy to perform a common sequence during installation
|
|
"make && sudo make install". A git process running under 'sudo' runs as
|
|
'root' but the 'sudo' command exports the environment variable to record
|
|
which id the original user has.
|
|
If that is not what you would prefer and want git to only trust
|
|
repositories that are owned by root instead, then you can remove
|
|
the `SUDO_UID` variable from root's environment before invoking git.
|