git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] transport: add core.allowProtocol config option

From
Jeff King <peff@peff.net>
Date
Nov 3, 2016, 18:24 UTC
Message-ID
<20161103182428.j3r574evsk7ypfie@sigill.intra.peff.net>
In-Reply-To
<20161103175327.nn2yasvlsxsy22be@sigill.intra.peff.net>
On Thu, Nov 03, 2016 at 01:53:27PM -0400, Jeff King wrote:
Show 6 quoted lines
> I'd design the new system from scratch, and have it kick in _only_ when
> GIT_ALLOW_PROTOCOL is not set. That lets existing callers continue to
> have the safe behavior until they are ready to move to the new format.
> 
> Something like the patch below (which is just for illustration, and not
> tested beyond compilation).
Here's that same patch with a few tweaks:
  - it changes git-submodule to use the new, more flexible system (which
    also gets a it a lot more test coverage)
  - it tweaks two tests which use the "ext" helper to enable it (since
    it's blacklisted by default; I have mixed feelings on that, but I
    see why Blake wants it, as it would have protected things like "go
    get" out of the box).
  - it adds "file://" as a known-good protocol, even for submodules,
    which matches the current code.  I am not sure if this is reasonable
    or not. A malicious repository probably can't do much by pointing
    you to cloning your own repo as a submodule unless you then _also_
    run some arbitrary code to expose it, at which point it's generally
    game-over anyway.
    And I'd expect automated services (like GitHub Pages) to already
    have a cut-down whitelist via GIT_ALLOW_PROTOCOL (and I happen to
    know that it goes).

So this seems like a reasonable direction to me. It obviously needs documentation and tests. Arguably there should be a fallback "allow" value when a protocol is not mentioned in the config so that you could convert the default from "user" to "never" if you wanted your config to specify a pure whitelist.

Without that, I think we'd want to keep GIT_ALLOW_PROTOCOL for the truly paranoid (though we should keep it indefinitely either way for backwards compatibility).

Do you have interest in picking this up and running with it?
-Peff
diff --git a/git-submodule.sh b/git-submodule.sh
index a024a135d..0a477b4c9 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -21,14 +21,10 @@ require_work_tree
 wt_prefix=$(git rev-parse --show-prefix)
 cd_to_toplevel
 
-# Restrict ourselves to a vanilla subset of protocols; the URLs
-# we get are under control of a remote repository, and we do not
-# want them kicking off arbitrary git-remote-* programs.
-#
-# If the user has already specified a set of allowed protocols,
-# we assume they know what they're doing and use that instead.
-: ${GIT_ALLOW_PROTOCOL=file:git:http:https:ssh}
-export GIT_ALLOW_PROTOCOL
+# Tell the rest of git that any URLs we get don't come
+# directly from the user, so it can apply policy as appropriate.
+GIT_PROTOCOL_FROM_USER=0
+export GIT_PROTOCOL_FROM_USER
 
 command=
 branch=
diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh
index bc44ac36d..75c570adc 100755
--- a/t/t5509-fetch-push-namespaces.sh
+++ b/t/t5509-fetch-push-namespaces.sh
@@ -4,6 +4,7 @@ test_description='fetch/push involving ref namespaces'
 . ./test-lib.sh
 
 test_expect_success setup '
+	git config --global protocol.ext.allow user &&
 	test_tick &&
 	git init original &&
 	(
diff --git a/t/t5802-connect-helper.sh b/t/t5802-connect-helper.sh
index b7a7f9d58..c6c266187 100755
--- a/t/t5802-connect-helper.sh
+++ b/t/t5802-connect-helper.sh
@@ -4,6 +4,7 @@ test_description='ext::cmd remote "connect" helper'
 . ./test-lib.sh
 
 test_expect_success setup '
+	git config --global protocol.ext.allow user &&
 	test_tick &&
 	git commit --allow-empty -m initial &&
 	test_tick &&
diff --git a/transport.c b/transport.c
index d57e8dec2..cd603fbf5 100644
--- a/transport.c
+++ b/transport.c
@@ -664,10 +664,70 @@ static const struct string_list *protocol_whitelist(void)
 	return enabled ? &allowed : NULL;
 }
 
+enum protocol_allow_config {
+	PROTOCOL_ALLOW_NEVER = 0,
+	PROTOCOL_ALLOW_USER_ONLY,
+	PROTOCOL_ALLOW_ALWAYS
+};
+
+static enum protocol_allow_config parse_protocol_config(const char *key,
+							const char *value)
+{
+	if (!strcasecmp(value, "always"))
+		return PROTOCOL_ALLOW_ALWAYS;
+	else if (!strcasecmp(value, "never"))
+		return PROTOCOL_ALLOW_NEVER;
+	else if (!strcasecmp(value, "user"))
+		return PROTOCOL_ALLOW_USER_ONLY;
+
+	/* XXX maybe also interpret git_config_bool() here? */
+	die("unknown value for config '%s': %s", key, value);
+}
+
+static enum protocol_allow_config get_protocol_config(const char *type)
+{
+	char *key = xstrfmt("protocol.%s.allow", type);
+	char *value;
+
+	if (!git_config_get_string(key, &value)) {
+		enum protocol_allow_config ret =
+			parse_protocol_config(key, value);
+		free(key);
+		free(value);
+		return ret;
+	}
+	free(key);
+
+	/* known safe */
+	if (!strcmp(type, "http") ||
+	    !strcmp(type, "https") ||
+	    !strcmp(type, "git") ||
+	    !strcmp(type, "ssh") ||
+	    !strcmp(type, "file"))
+		return PROTOCOL_ALLOW_ALWAYS;
+
+	/* known scary; err on the side of caution */
+	if (!strcmp(type, "ext"))
+		return PROTOCOL_ALLOW_NEVER;
+
+	/* unknown; let them be used only directly by the user */
+	return PROTOCOL_ALLOW_USER_ONLY;
+}
+
 int is_transport_allowed(const char *type)
 {
-	const struct string_list *allowed = protocol_whitelist();
-	return !allowed || string_list_has_string(allowed, type);
+	const struct string_list *whitelist = protocol_whitelist();
+	if (whitelist)
+		return string_list_has_string(whitelist, type);
+
+	switch (get_protocol_config(type)) {
+	case PROTOCOL_ALLOW_ALWAYS:
+		return 1;
+	case PROTOCOL_ALLOW_NEVER:
+		return 0;
+	case PROTOCOL_ALLOW_USER_ONLY:
+		return git_env_bool("GIT_PROTOCOL_FROM_USER", 1);
+	}
 }
 
 void transport_check_allowed(const char *type)
Previous: Jeff KingNext: Brandon Williams
Message 23 of 117 in “transport: add core.allowProtocol config option”
  1. transport: add core.allowProtocol config optionBrandon Williams, Nov 2, 2016
  2. Stefan BellerNov 2, 2016
  3. Brandon WilliamsNov 2, 2016
  4. Jeff KingNov 2, 2016
  5. Jeff KingNov 2, 2016
  6. Brandon WilliamsNov 2, 2016
  7. Brandon WilliamsNov 2, 2016
  8. Brandon WilliamsNov 2, 2016
  9. Jeff KingNov 3, 2016
  10. Jonathan NiederNov 3, 2016
  11. Blake BurkhartNov 3, 2016
  12. Junio C HamanoNov 3, 2016
  13. Jeff KingNov 3, 2016
  14. Brandon WilliamsNov 3, 2016
  15. Stefan BellerNov 3, 2016
  16. Brandon WilliamsNov 3, 2016
  17. Jeff KingNov 3, 2016
  18. Brandon WilliamsNov 3, 2016
  19. Jeff KingNov 3, 2016
  20. Jeff KingNov 3, 2016
  21. Brandon WilliamsNov 3, 2016
  22. Jeff KingNov 3, 2016
  23. Jeff KingNov 3, 2016
  24. Brandon WilliamsNov 3, 2016
  25. Jeff KingNov 3, 2016
  26. Brandon WilliamsNov 3, 2016
  27. transport: add core.allowProtocol config optionBrandon Williams, Nov 3, 2016
  28. transport: add protocol policy config optionBrandon Williams, Nov 4, 2016
  29. Brandon WilliamsNov 4, 2016
  30. Stefan BellerNov 4, 2016
  31. Jeff KingNov 4, 2016
  32. Brandon WilliamsNov 5, 2016
  33. Stefan BellerNov 4, 2016
  34. Brandon WilliamsNov 7, 2016
  35. Jeff KingNov 4, 2016
  36. Brandon WilliamsNov 7, 2016
  37. 1/2 lib-proto-disable: variable name fixBrandon Williams, Nov 7, 2016
  38. 2/2 transport: add protocol policy config optionBrandon Williams, Nov 7, 2016
  39. Jeff KingNov 7, 2016
  40. Brandon WilliamsNov 7, 2016
  41. Jeff KingNov 7, 2016
  42. Brandon WilliamsNov 7, 2016
  43. Jeff KingNov 7, 2016
  44. Jacob KellerNov 8, 2016
  45. Junio C HamanoNov 8, 2016
  46. 1/2 lib-proto-disable: variable name fixBrandon Williams, Nov 7, 2016
  47. 2/2 transport: add protocol policy config optionBrandon Williams, Nov 7, 2016
  48. Jeff KingNov 8, 2016
  49. Brandon WilliamsNov 8, 2016
  50. 0/4 transport protocol policy configurationBrandon Williams, Dec 1, 2016
  51. 4/4 transport: check if protocol can be used on a redirectBrandon Williams, Dec 1, 2016
  52. 4/4 transport: check if protocol can be used on a redirectBrandon Williams, Dec 1, 2016
  53. Brandon WilliamsDec 1, 2016
  54. Jeff KingDec 1, 2016
  55. Junio C HamanoDec 1, 2016
  56. Jeff KingDec 1, 2016
  57. Brandon WilliamsDec 1, 2016
  58. 2/4 transport: add protocol policy config optionBrandon Williams, Dec 1, 2016
  59. 1/4 lib-proto-disable: variable name fixBrandon Williams, Dec 1, 2016
  60. 3/4 http: always warn if libcurl version is too oldBrandon Williams, Dec 1, 2016
  61. 0/4 transport protocol policy configurationBrandon Williams, Dec 1, 2016
  62. 3/4 http: always warn if libcurl version is too oldBrandon Williams, Dec 1, 2016
  63. 1/4 lib-proto-disable: variable name fixBrandon Williams, Dec 1, 2016
  64. 2/4 transport: add protocol policy config optionBrandon Williams, Dec 1, 2016
  65. 4/4 transport: add from_user parameter to is_transport_allowedBrandon Williams, Dec 1, 2016
  66. Jeff KingDec 1, 2016
  67. Junio C HamanoDec 1, 2016
  68. Brandon WilliamsDec 1, 2016
  69. Brandon WilliamsDec 1, 2016
  70. Jeff KingDec 2, 2016
  71. Brandon WilliamsDec 2, 2016
  72. Junio C HamanoDec 1, 2016
  73. Brandon WilliamsDec 1, 2016
  74. Junio C HamanoDec 5, 2016
  75. Brandon WilliamsDec 5, 2016
  76. Junio C HamanoDec 5, 2016
  77. Brandon WilliamsDec 5, 2016
  78. Jeff KingDec 6, 2016
  79. Junio C HamanoDec 6, 2016
  80. Jeff KingDec 6, 2016
  81. Brandon WilliamsDec 6, 2016
  82. 0/5 transport protocol policy configurationBrandon Williams, Dec 2, 2016
  83. 1/5 lib-proto-disable: variable name fixBrandon Williams, Dec 2, 2016
  84. 3/5 http: always warn if libcurl version is too oldBrandon Williams, Dec 2, 2016
  85. 5/5 transport: add from_user parameter to is_transport_allowedBrandon Williams, Dec 2, 2016
  86. 2/5 transport: add protocol policy config optionBrandon Williams, Dec 2, 2016
  87. 4/5 http: create function to get curl allowed protocolsBrandon Williams, Dec 2, 2016
  88. 0/5 transport protocol policy configurationBrandon Williams, Dec 14, 2016
  89. 1/5 lib-proto-disable: variable name fixBrandon Williams, Dec 14, 2016
  90. 2/5 transport: add protocol policy config optionBrandon Williams, Dec 14, 2016
  91. 3/5 http: always warn if libcurl version is too oldBrandon Williams, Dec 14, 2016
  92. Jeff KingDec 14, 2016
  93. Brandon WilliamsDec 14, 2016
  94. 4/5 http: create function to get curl allowed protocolsBrandon Williams, Dec 14, 2016
  95. Jeff KingDec 14, 2016
  96. Brandon WilliamsDec 14, 2016
  97. 5/5 transport: add from_user parameter to is_transport_allowedBrandon Williams, Dec 14, 2016
  98. Jeff KingDec 14, 2016
  99. Brandon WilliamsDec 14, 2016
  100. Jeff KingDec 14, 2016
  101. Jeff KingDec 14, 2016
  102. Brandon WilliamsDec 14, 2016
  103. Brandon WilliamsDec 14, 2016
  104. Jeff KingDec 14, 2016
  105. Brandon WilliamsDec 14, 2016
  106. 0/6 transport protocol policy configurationBrandon Williams, Dec 14, 2016
  107. 2/6 http: always warn if libcurl version is too oldBrandon Williams, Dec 14, 2016
  108. Jeff KingDec 15, 2016
  109. Junio C HamanoDec 15, 2016
  110. 3/6 transport: add protocol policy config optionBrandon Williams, Dec 14, 2016
  111. 5/6 transport: add from_user parameter to is_transport_allowedBrandon Williams, Dec 14, 2016
  112. 6/6 http: respect protocol.*.allow=user for http-alternatesBrandon Williams, Dec 14, 2016
  113. 4/6 http: create function to get curl allowed protocolsBrandon Williams, Dec 14, 2016
  114. 1/6 lib-proto-disable: variable name fixBrandon Williams, Dec 14, 2016
  115. Junio C HamanoDec 14, 2016
  116. Jeff KingDec 15, 2016
  117. Jeff KingDec 14, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.