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

Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions

From
Jeff King <peff@peff.net>
Date
Aug 22, 2022, 09:04 UTC
Message-ID
<YwNGoqcx3c27XpQL@coredump.intra.peff.net>
In-Reply-To
<o4sp3o6-75sp-o12o-2p29-r94s2s769r47@unkk.fr>
On Sun, Aug 21, 2022 at 12:32:54AM +0200, Daniel Stenberg wrote:
Show 5 quoted lines
> I would not mind having a discussion in the curl project to see if we should
> possibly consider adding a middle-ground where we allow sending credentials
> to another port for the same host name, but I am personally NOT sold on the
> idea. I think such redirects should rather be fixed and avoided - since I
> believe users will not understand the security implications of doing them.

I'm not 100% on it either. When it comes to security restrictions, sometimes simple-and-stupid is the best way. I was literally thinking of something as basic and restricted as:

  if (from_port == 80 && to_port == 443 &&
      from_protocol == HTTP && to_protocol == HTTPS)
        /* ok, allow it */

just because https upgrade is such a common (and presumably harmless) redirect. But possibly even that leaves wiggle room for bad things to happen. I'm happy to defer to you and other curl folks there.

I think the worst thing about the user experience from Git here is that it says "authentication failed", which is indistinguishable from a bogus credential. We don't even mention the redirect, because we don't warn about them unless the request ends up successful!

So I was thinking that curl could tell us "hey, I cleared the auth due to a redirect" via some curl_easy_getinfo() call. But maybe just noticing there was a redirect would be sufficient. This seems to work:

diff --git a/http.c b/http.c
index 5d0502f51f..0fe8a906e5 100644
--- a/http.c
+++ b/http.c
@@ -1934,7 +1934,7 @@ static int http_request_reauth(const char *url,
 {
 	int ret = http_request(url, result, target, options);
 
-	if (ret != HTTP_OK && ret != HTTP_REAUTH)
+	if (ret != HTTP_OK && ret != HTTP_REAUTH && ret != HTTP_NOAUTH)
 		return ret;
 
 	if (options && options->effective_url && options->base_url) {
diff --git a/remote-curl.c b/remote-curl.c
index b8758757ec..d462077a97 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -501,6 +501,12 @@ static struct discovery *discover_refs(const char *service, int for_push)
 		    transport_anonymize_url(url.buf));
 	case HTTP_NOAUTH:
 		show_http_message(&type, &charset, &buffer);
+		if (LIBCURL_VERSION_NUM >= 0x075300 &&
+		    strcmp(refs_url.buf, effective_url.buf)) {
+			char *u = transport_anonymize_url(url.buf);
+			warning(_("request redirected to %s"), u);
+			warning(_("authentication information may have been discarded"));
+		}
 		die(_("Authentication failed for '%s'"),
 		    transport_anonymize_url(url.buf));
 	case HTTP_NOMATCHPUBLICKEY:

Though I wonder if there is a cleaner way to determine what happened
than string comparisons.

-Peff
Previous: Jeff KingNext: brian m. carlson
Message 7 of 9 in “git clone with basic auth in url directly returns authentication failure after 401 received under some git versions”
  1. 王小建Aug 20, 2022
  2. Jeff KingAug 20, 2022
  3. 王小建Aug 20, 2022
  4. Daniel StenbergAug 20, 2022
  5. 王小建Aug 22, 2022
  6. Jeff KingAug 22, 2022
  7. Jeff KingAug 22, 2022
  8. brian m. carlsonAug 22, 2022
  9. Jeff KingAug 23, 2022

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.