]> git.ipfire.org Git - thirdparty/git.git/commitdiff
transport: make `protocol.file.allow` be "user" by default
authorTaylor Blau <me@ttaylorr.com>
Fri, 29 Jul 2022 19:22:13 +0000 (15:22 -0400)
committerTaylor Blau <me@ttaylorr.com>
Sat, 1 Oct 2022 04:23:38 +0000 (00:23 -0400)
An earlier patch discussed and fixed a scenario where Git could be used
as a vector to exfiltrate sensitive data through a Docker container when
a potential victim clones a suspicious repository with local submodules
that contain symlinks.

That security hole has since been plugged, but a similar one still
exists.  Instead of convincing a would-be victim to clone an embedded
submodule via the "file" protocol, an attacker could convince an
individual to clone a repository that has a submodule pointing to a
valid path on the victim's filesystem.

For example, if an individual (with username "foo") has their home
directory ("/home/foo") stored as a Git repository, then an attacker
could exfiltrate data by convincing a victim to clone a malicious
repository containing a submodule pointing at "/home/foo/.git" with
`--recurse-submodules`. Doing so would expose any sensitive contents in
stored in "/home/foo" tracked in Git.

For systems (such as Docker) that consider everything outside of the
immediate top-level working directory containing a Dockerfile as
inaccessible to the container (with the exception of volume mounts, and
so on), this is a violation of trust by exposing unexpected contents in
the working copy.

To mitigate the likelihood of this kind of attack, adjust the "file://"
protocol's default policy to be "user" to prevent commands that execute
without user input (including recursive submodule initialization) from
taking place by default.

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Documentation/config/protocol.txt
transport.c

index 756591d77b080ccfe5be5a26c899b65273cf4866..799389132f07b59e0280bbad612ec62c2bbc17dc 100644 (file)
@@ -1,10 +1,10 @@
 protocol.allow::
        If set, provide a user defined default policy for all protocols which
        don't explicitly have a policy (`protocol.<name>.allow`).  By default,
-       if unset, known-safe protocols (http, https, git, ssh, file) have a
+       if unset, known-safe protocols (http, https, git, ssh) have a
        default policy of `always`, known-dangerous protocols (ext) have a
-       default policy of `never`, and all other protocols have a default
-       policy of `user`.  Supported policies:
+       default policy of `never`, and all other protocols (including file)
+       have a default policy of `user`.  Supported policies:
 +
 --
 
index 679a35e7c1b6168d3b8fc93f72ec9a50178d894c..d2e3a90de16651e7af8e568d5741f6d59fccd40d 100644 (file)
@@ -964,8 +964,7 @@ static enum protocol_allow_config get_protocol_config(const char *type)
        if (!strcmp(type, "http") ||
            !strcmp(type, "https") ||
            !strcmp(type, "git") ||
-           !strcmp(type, "ssh") ||
-           !strcmp(type, "file"))
+           !strcmp(type, "ssh"))
                return PROTOCOL_ALLOW_ALWAYS;
 
        /* known scary; err on the side of caution */