diff options
-rw-r--r-- | Documentation/git.txt | 5 | ||||
-rw-r--r-- | http.c | 17 | ||||
-rw-r--r-- | t/lib-httpd/apache.conf | 1 | ||||
-rwxr-xr-x | t/t5812-proto-disable-http.sh | 9 |
4 files changed, 27 insertions, 5 deletions
diff --git a/Documentation/git.txt b/Documentation/git.txt index b6a12b32ee..41a09cac7a 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -1071,11 +1071,6 @@ GIT_ICASE_PATHSPECS:: - any external helpers are named by their protocol (e.g., use `hg` to allow the `git-remote-hg` helper) -+ -Note that this controls only git's internal protocol selection. -If libcurl is used (e.g., by the `http` transport), it may -redirect to other protocols. There is not currently any way to -restrict this. Discussion[[Discussion]] @@ -8,6 +8,7 @@ #include "credential.h" #include "version.h" #include "pkt-line.h" +#include "transport.h" int active_requests; int http_is_verbose; @@ -303,6 +304,7 @@ static void set_curl_keepalive(CURL *c) static CURL *get_curl_handle(void) { CURL *result = curl_easy_init(); + long allowed_protocols = 0; if (!result) die("curl_easy_init failed"); @@ -355,6 +357,21 @@ static CURL *get_curl_handle(void) #elif LIBCURL_VERSION_NUM >= 0x071101 curl_easy_setopt(result, CURLOPT_POST301, 1); #endif +#if LIBCURL_VERSION_NUM >= 0x071304 + if (is_transport_allowed("http")) + allowed_protocols |= CURLPROTO_HTTP; + if (is_transport_allowed("https")) + allowed_protocols |= CURLPROTO_HTTPS; + if (is_transport_allowed("ftp")) + allowed_protocols |= CURLPROTO_FTP; + if (is_transport_allowed("ftps")) + allowed_protocols |= CURLPROTO_FTPS; + curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS, allowed_protocols); +#else + if (transport_restrict_protocols()) + warning("protocol restrictions not applied to curl redirects because\n" + "your curl version is too old (>= 7.19.4)"); +#endif if (getenv("GIT_CURL_VERBOSE")) curl_easy_setopt(result, CURLOPT_VERBOSE, 1); diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 0b81a0047b..68ef8adb8e 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -119,6 +119,7 @@ RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301] RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302] RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301] RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301] +RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302] <IfDefine SSL> LoadModule ssl_module modules/mod_ssl.so diff --git a/t/t5812-proto-disable-http.sh b/t/t5812-proto-disable-http.sh index dd5001cbac..6a4f81662d 100755 --- a/t/t5812-proto-disable-http.sh +++ b/t/t5812-proto-disable-http.sh @@ -16,5 +16,14 @@ test_expect_success 'create git-accessible repo' ' test_proto "smart http" http "$HTTPD_URL/smart/repo.git" +test_expect_success 'curl redirects respect whitelist' ' + test_must_fail env GIT_ALLOW_PROTOCOL=http:https \ + git clone "$HTTPD_URL/ftp-redir/repo.git" 2>stderr && + { + test_i18ngrep "ftp.*disabled" stderr || + test_i18ngrep "your curl version is too old" + } +' + stop_httpd test_done |