| Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 1 | From 33cfccbbf35a56e190b79bdec5c85457c952a021 Mon Sep 17 00:00:00 2001 | 
|  | 2 | From: Jeff King <peff@peff.net> | 
|  | 3 | Date: Wed, 16 Sep 2015 13:13:12 -0400 | 
|  | 4 | Subject: [PATCH] submodule: allow only certain protocols for submodule fetches | 
|  | 5 |  | 
|  | 6 | Some protocols (like git-remote-ext) can execute arbitrary | 
|  | 7 | code found in the URL. The URLs that submodules use may come | 
|  | 8 | from arbitrary sources (e.g., .gitmodules files in a remote | 
|  | 9 | repository). Let's restrict submodules to fetching from a | 
|  | 10 | known-good subset of protocols. | 
|  | 11 |  | 
|  | 12 | Note that we apply this restriction to all submodule | 
|  | 13 | commands, whether the URL comes from .gitmodules or not. | 
|  | 14 | This is more restrictive than we need to be; for example, in | 
|  | 15 | the tests we run: | 
|  | 16 |  | 
|  | 17 | git submodule add ext::... | 
|  | 18 |  | 
|  | 19 | which should be trusted, as the URL comes directly from the | 
|  | 20 | command line provided by the user. But doing it this way is | 
|  | 21 | simpler, and makes it much less likely that we would miss a | 
|  | 22 | case. And since such protocols should be an exception | 
|  | 23 | (especially because nobody who clones from them will be able | 
|  | 24 | to update the submodules!), it's not likely to inconvenience | 
|  | 25 | anyone in practice. | 
|  | 26 |  | 
|  | 27 | Reported-by: Blake Burkhart <bburky@bburky.com> | 
|  | 28 | Signed-off-by: Jeff King <peff@peff.net> | 
|  | 29 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | 
|  | 30 |  | 
|  | 31 | Upstream-Status: Backport | 
|  | 32 |  | 
|  | 33 | http://archive.ubuntu.com/ubuntu/pool/main/g/git/git_2.5.0-1ubuntu0.1.debian.tar.xz | 
|  | 34 |  | 
|  | 35 | CVE: CVE-2015-7545 #2 | 
|  | 36 | Singed-off-by: Armin Kuster <akuster@mvista.com> | 
|  | 37 |  | 
|  | 38 | --- | 
|  | 39 | git-submodule.sh            |  9 +++++++++ | 
|  | 40 | t/t5815-submodule-protos.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ | 
|  | 41 | 2 files changed, 52 insertions(+) | 
|  | 42 | create mode 100755 t/t5815-submodule-protos.sh | 
|  | 43 |  | 
|  | 44 | diff --git a/git-submodule.sh b/git-submodule.sh | 
|  | 45 | index 36797c3..78c2740 100755 | 
|  | 46 | --- a/git-submodule.sh | 
|  | 47 | +++ b/git-submodule.sh | 
|  | 48 | @@ -22,6 +22,15 @@ require_work_tree | 
|  | 49 | wt_prefix=$(git rev-parse --show-prefix) | 
|  | 50 | cd_to_toplevel | 
|  | 51 |  | 
|  | 52 | +# Restrict ourselves to a vanilla subset of protocols; the URLs | 
|  | 53 | +# we get are under control of a remote repository, and we do not | 
|  | 54 | +# want them kicking off arbitrary git-remote-* programs. | 
|  | 55 | +# | 
|  | 56 | +# If the user has already specified a set of allowed protocols, | 
|  | 57 | +# we assume they know what they're doing and use that instead. | 
|  | 58 | +: ${GIT_ALLOW_PROTOCOL=file:git:http:https:ssh} | 
|  | 59 | +export GIT_ALLOW_PROTOCOL | 
|  | 60 | + | 
|  | 61 | command= | 
|  | 62 | branch= | 
|  | 63 | force= | 
|  | 64 | diff --git a/t/t5815-submodule-protos.sh b/t/t5815-submodule-protos.sh | 
|  | 65 | new file mode 100755 | 
|  | 66 | index 0000000..06f55a1 | 
|  | 67 | --- /dev/null | 
|  | 68 | +++ b/t/t5815-submodule-protos.sh | 
|  | 69 | @@ -0,0 +1,43 @@ | 
|  | 70 | +#!/bin/sh | 
|  | 71 | + | 
|  | 72 | +test_description='test protocol whitelisting with submodules' | 
|  | 73 | +. ./test-lib.sh | 
|  | 74 | +. "$TEST_DIRECTORY"/lib-proto-disable.sh | 
|  | 75 | + | 
|  | 76 | +setup_ext_wrapper | 
|  | 77 | +setup_ssh_wrapper | 
|  | 78 | + | 
|  | 79 | +test_expect_success 'setup repository with submodules' ' | 
|  | 80 | +	mkdir remote && | 
|  | 81 | +	git init remote/repo.git && | 
|  | 82 | +	(cd remote/repo.git && test_commit one) && | 
|  | 83 | +	# submodule-add should probably trust what we feed it on the cmdline, | 
|  | 84 | +	# but its implementation is overly conservative. | 
|  | 85 | +	GIT_ALLOW_PROTOCOL=ssh git submodule add remote:repo.git ssh-module && | 
|  | 86 | +	GIT_ALLOW_PROTOCOL=ext git submodule add "ext::fake-remote %S repo.git" ext-module && | 
|  | 87 | +	git commit -m "add submodules" | 
|  | 88 | +' | 
|  | 89 | + | 
|  | 90 | +test_expect_success 'clone with recurse-submodules fails' ' | 
|  | 91 | +	test_must_fail git clone --recurse-submodules . dst | 
|  | 92 | +' | 
|  | 93 | + | 
|  | 94 | +test_expect_success 'setup individual updates' ' | 
|  | 95 | +	rm -rf dst && | 
|  | 96 | +	git clone . dst && | 
|  | 97 | +	git -C dst submodule init | 
|  | 98 | +' | 
|  | 99 | + | 
|  | 100 | +test_expect_success 'update of ssh allowed' ' | 
|  | 101 | +	git -C dst submodule update ssh-module | 
|  | 102 | +' | 
|  | 103 | + | 
|  | 104 | +test_expect_success 'update of ext not allowed' ' | 
|  | 105 | +	test_must_fail git -C dst submodule update ext-module | 
|  | 106 | +' | 
|  | 107 | + | 
|  | 108 | +test_expect_success 'user can override whitelist' ' | 
|  | 109 | +	GIT_ALLOW_PROTOCOL=ext git -C dst submodule update ext-module | 
|  | 110 | +' | 
|  | 111 | + | 
|  | 112 | +test_done |