{"thread":{"id":"58334","subject":"git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","startedAt":"2022-08-20T02:51:36Z","lastAt":"2022-08-23T20:36:01Z","messageCount":9,"participants":["王小建","Jeff King","Daniel Stenberg","brian m. carlson"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"461643","messageId":"CADmGLV32OAg6HU+n1UsP2Fq-MjcyUsFFF=q0_jZCB0JEop5VUg@mail.gmail.com","threadId":"58334","inReplyTo":null,"subject":"git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"王小建","fromEmail":"littlejian8@gmail.com","sentAt":"2022-08-20T02:51:16Z","receivedAt":"2022-08-20T02:51:36Z","isPatch":false,"sender":{"key":"littlejian8@gmail.com","avatar":null},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\nI want to git clone with basic auth in url, such as git clone\nhttp://xxx:xxx@xxx.xxx/xxx/xxx\n\nWhat did you expect to happen? (Expected behavior)\n\nClone successfully\n\nWhat happened instead? (Actual behavior)\n\nfatal: Authentication failed\n\nWhat's different between what you expected and what actually happened?\n\nWhen I use git v2.36.2  (docker image is alpine/git:v2.36.2) to clone\nwith basic auth in url, when receiving the 401, it directly returns\nauthentication failure, even recv head has www-authenticate: Basic\nrealm=Restricted,\nand no request is send again. I think it should send request with\nauthorization: Basic header after receive 401.\nAnd use git v2.34.2 (docker image is alpine/git:v2.34.1) to clone it works well.\n\n\nAnything else you want to add:\n\n$ server git version: git version 2.30.2\n\n Below is the GIT_CURL_VERBOSE information between 2 versions\n\n GIT_CURL_VERBOSE info with v2.36.2 (docker image is alpine/git:v2.36.2) Output:\n $ docker run -it -e GIT_CURL_VERBOSE=1 5de1a96efc49  clone\nhttp://xxx:xxx@xxx.xxx/xxx/xxx\nCloning into 'xxx'...\n10:54:06.204996 http.c:664              == Info:   Trying xxx.xxx.xxx.xxx:80...\n10:54:06.235057 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx.xxx) port 80 (#0)\n10:54:06.235347 http.c:611              => Send header, 0000000221\nbytes (0x000000dd)\n10:54:06.235406 http.c:623              => Send header: GET\n/xxx/xxx/info/refs?service=git-upload-pack HTTP/1.1\n10:54:06.235665 http.c:623              => Send header: Host: xxx.xxx\n10:54:06.235677 http.c:623              => Send header: User-Agent: git/2.36.2\n10:54:06.235687 http.c:623              => Send header: Accept: */*\n10:54:06.235701 http.c:623              => Send header:\nAccept-Encoding: deflate, gzip, br\n10:54:06.235712 http.c:623              => Send header: Pragma: no-cache\n10:54:06.235727 http.c:623              => Send header: Git-Protocol: version=2\n10:54:06.235779 http.c:623              => Send header:\n10:54:06.240590 http.c:664              == Info: Mark bundle as not\nsupporting multiuse\n10:54:06.240658 http.c:611              <= Recv header, 0000000020\nbytes (0x00000014)\n10:54:06.240677 http.c:623              <= Recv header: HTTP/1.1 302 Found\n10:54:06.240692 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n10:54:06.240700 http.c:623              <= Recv header: Date: Fri, 19\nAug 2022 10:54:06 GMT\n10:54:06.240713 http.c:611              <= Recv header, 0000000025\nbytes (0x00000019)\n10:54:06.240723 http.c:623              <= Recv header: Content-Type: text/html\n10:54:06.240737 http.c:611              <= Recv header, 0000000021\nbytes (0x00000015)\n10:54:06.240753 http.c:623              <= Recv header: Content-Length: 154\n10:54:06.240801 http.c:611              <= Recv header, 0000000024\nbytes (0x00000018)\n10:54:06.240812 http.c:623              <= Recv header: Connection: keep-alive\n10:54:06.240828 http.c:611              <= Recv header, 0000000100\nbytes (0x00000064)\n10:54:06.240839 http.c:623              <= Recv header: Location:\nhttps://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack\n10:54:06.240847 http.c:611              <= Recv header, 0000000022\nbytes (0x00000016)\n10:54:06.240857 http.c:623              <= Recv header: Via: HTTP/1.1 SLB.25\n10:54:06.240868 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n10:54:06.240876 http.c:623              <= Recv header:\n10:54:06.240884 http.c:664              == Info: Ignoring the response-body\n10:54:06.241141 http.c:664              == Info: Connection #0 to host\nxxx.xxx left intact\n10:54:06.241331 http.c:664              == Info: Clear auth, redirects\nto port from 80 to 443\n10:54:06.241350 http.c:664              == Info: Issue another request\nto this URL: 'https://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack'\n10:54:06.241480 http.c:664              == Info: NTLM-proxy picked AND\nauth done set, clear picked\n10:54:06.248582 http.c:664              == Info:   Trying xxx.xxx.xxx.xxx:443...\n10:54:06.254035 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx.xxx) port 443 (#1)\n10:54:06.254672 http.c:664              == Info: ALPN: offers h2\n10:54:06.254723 http.c:664              == Info: ALPN: offers http/1.1\n10:54:06.267498 http.c:664              == Info:  CAfile:\n/etc/ssl/certs/ca-certificates.crt\n10:54:06.267561 http.c:664              == Info:  CApath: none\n10:54:06.267838 http.c:664              == Info: TLSv1.3 (OUT), TLS\nhandshake, Client hello (1):\n10:54:06.277311 http.c:664              == Info: TLSv1.3 (IN), TLS\nhandshake, Server hello (2):\n10:54:06.277427 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Certificate (11):\n10:54:06.278079 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Server key exchange (12):\n10:54:06.278272 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Server finished (14):\n10:54:06.278609 http.c:664              == Info: TLSv1.2 (OUT), TLS\nhandshake, Client key exchange (16):\n10:54:06.278685 http.c:664              == Info: TLSv1.2 (OUT), TLS\nchange cipher, Change cipher spec (1):\n10:54:06.278797 http.c:664              == Info: TLSv1.2 (OUT), TLS\nhandshake, Finished (20):\n10:54:06.284962 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Finished (20):\n10:54:06.285064 http.c:664              == Info: SSL connection using\nTLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256\n10:54:06.285082 http.c:664              == Info: ALPN: server accepted h2\n10:54:06.285101 http.c:664              == Info: Server certificate:\n10:54:06.285116 http.c:664              == Info:  subject: CN=*.xxx.xxx\n10:54:06.285133 http.c:664              == Info:  start date: Apr  8\n00:00:00 2022 GMT\n10:54:06.285254 http.c:664              == Info:  expire date: Apr  9\n23:59:59 2023 GMT\n10:54:06.285317 http.c:664              == Info:  subjectAltName: host\n\"xxx.xxx\" matched cert's \"*.xxx.xxx\"\n10:54:06.285364 http.c:664              == Info:  issuer: C=US;\nO=DigiCert Inc; CN=RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1\n10:54:06.285374 http.c:664              == Info:  SSL certificate verify ok.\n10:54:06.285460 http.c:664              == Info: Using HTTP2, server\nsupports multiplexing\n10:54:06.285508 http.c:664              == Info: Copying HTTP/2 data\nin stream buffer to connection buffer after upgrade: len=0\n10:54:06.285902 http.c:664              == Info: h2h3 [:method: GET]\n10:54:06.285956 http.c:664              == Info: h2h3 [:path:\n/xxx/xxx/info/refs?service=git-upload-pack]\n10:54:06.285977 http.c:664              == Info: h2h3 [:scheme: https]\n10:54:06.285996 http.c:664              == Info: h2h3 [:authority: xxx.xxx]\n10:54:06.286011 http.c:664              == Info: h2h3 [user-agent: git/2.36.2]\n10:54:06.286019 http.c:664              == Info: h2h3 [accept: */*]\n10:54:06.286029 http.c:664              == Info: h2h3\n[accept-encoding: deflate, gzip, br]\n10:54:06.286039 http.c:664              == Info: h2h3 [pragma: no-cache]\n10:54:06.286048 http.c:664              == Info: h2h3 [git-protocol: version=2]\n10:54:06.286075 http.c:664              == Info: Using Stream ID: 1\n(easy handle 0x7f4673e9e210)\n10:54:06.286401 http.c:611              => Send header, 0000000219\nbytes (0x000000db)\n10:54:06.286459 http.c:623              => Send header: GET\n/xxx/xxx/info/refs?service=git-upload-pack HTTP/2\n10:54:06.286473 http.c:623              => Send header: Host: xxx.xxx\n10:54:06.286481 http.c:623              => Send header: user-agent: git/2.36.2\n10:54:06.286495 http.c:623              => Send header: accept: */*\n10:54:06.286562 http.c:623              => Send header:\naccept-encoding: deflate, gzip, br\n10:54:06.286604 http.c:623              => Send header: pragma: no-cache\n10:54:06.286647 http.c:623              => Send header: git-protocol: version=2\n10:54:06.286694 http.c:623              => Send header:\n10:54:06.286835 http.c:664              == Info: Connection state\nchanged (MAX_CONCURRENT_STREAMS == 128)!\n10:54:06.296853 http.c:611              <= Recv header, 0000000013\nbytes (0x0000000d)\n10:54:06.296907 http.c:623              <= Recv header: HTTP/2 401\n10:54:06.296924 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n10:54:06.296939 http.c:623              <= Recv header: date: Fri, 19\nAug 2022 10:54:06 GMT\n10:54:06.296952 http.c:611              <= Recv header, 0000000047\nbytes (0x0000002f)\n10:54:06.296964 http.c:623              <= Recv header: content-type:\napplication/json; charset=UTF-8\n10:54:06.297008 http.c:611              <= Recv header, 0000000020\nbytes (0x00000014)\n10:54:06.297023 http.c:623              <= Recv header: content-length: 69\n10:54:06.297035 http.c:611              <= Recv header, 0000000070\nbytes (0x00000046)\n10:54:06.297043 http.c:623              <= Recv header: traceparent:\n00-ad497b554e2addf5b0a94937024187c4-138a06a14cd9ed47-01\n10:54:06.297083 http.c:611              <= Recv header, 0000000042\nbytes (0x0000002a)\n10:54:06.297099 http.c:623              <= Recv header:\nwww-authenticate: Basic realm=Restricted\n10:54:06.297116 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n10:54:06.297125 http.c:623              <= Recv header:\n10:54:06.297313 http.c:664              == Info: Connection #1 to host\nxxx.xxx left intact\nfatal: Authentication failed for 'http://xxx.xxx/xxx/xxx/'\n\n GIT_CURL_VERBOSE info with v2.34.2 (docker image is alpine/git:v2.34.1) Output:\n$ docker run -it -e GIT_CURL_VERBOSE=1  aaee7a44d8d4  clone\nhttp://xxx:xxx@xxx.xxx/xxx/xxx\nCloning into 'xxx'...\n11:11:10.183612 http.c:664              == Info:   Trying xxx.xxx.xxx:80...\n11:11:10.190536 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx) port 80 (#0)\n11:11:10.190719 http.c:611              => Send header, 0000000221\nbytes (0x000000dd)\n11:11:10.190798 http.c:623              => Send header: GET\n/xxx/xxx/info/refs?service=git-upload-pack HTTP/1.1\n11:11:10.190815 http.c:623              => Send header: Host: xxx.xxx\n11:11:10.190828 http.c:623              => Send header: User-Agent: git/2.34.2\n11:11:10.190836 http.c:623              => Send header: Accept: */*\n11:11:10.190844 http.c:623              => Send header:\nAccept-Encoding: deflate, gzip, br\n11:11:10.190875 http.c:623              => Send header: Pragma: no-cache\n11:11:10.190883 http.c:623              => Send header: Git-Protocol: version=2\n11:11:10.190891 http.c:623              => Send header:\n11:11:10.196034 http.c:664              == Info: Mark bundle as not\nsupporting multiuse\n11:11:10.196086 http.c:611              <= Recv header, 0000000020\nbytes (0x00000014)\n11:11:10.196104 http.c:623              <= Recv header: HTTP/1.1 302 Found\n11:11:10.196120 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n11:11:10.196133 http.c:623              <= Recv header: Date: Fri, 19\nAug 2022 11:11:10 GMT\n11:11:10.196272 http.c:611              <= Recv header, 0000000025\nbytes (0x00000019)\n11:11:10.196289 http.c:623              <= Recv header: Content-Type: text/html\n11:11:10.196305 http.c:611              <= Recv header, 0000000021\nbytes (0x00000015)\n11:11:10.196318 http.c:623              <= Recv header: Content-Length: 154\n11:11:10.196362 http.c:611              <= Recv header, 0000000024\nbytes (0x00000018)\n11:11:10.196396 http.c:623              <= Recv header: Connection: keep-alive\n11:11:10.196413 http.c:611              <= Recv header, 0000000100\nbytes (0x00000064)\n11:11:10.196429 http.c:623              <= Recv header: Location:\nhttps://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack\n11:11:10.196463 http.c:611              <= Recv header, 0000000022\nbytes (0x00000016)\n11:11:10.196504 http.c:623              <= Recv header: Via: HTTP/1.1 SLB.27\n11:11:10.196544 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n11:11:10.196555 http.c:623              <= Recv header:\n11:11:10.196564 http.c:664              == Info: Ignoring the response-body\n11:11:10.196649 http.c:664              == Info: Connection #0 to host\nxxx.xxx left intact\n11:11:10.196718 http.c:664              == Info: Issue another request\nto this URL: 'https://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack'\n11:11:10.196869 http.c:664              == Info: NTLM-proxy picked AND\nauth done set, clear picked!\n11:11:10.202506 http.c:664              == Info:   Trying xxx.xxx.xxx:443...\n11:11:10.208418 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx) port 443 (#1)\n11:11:10.208923 http.c:664              == Info: ALPN, offering h2\n11:11:10.208964 http.c:664              == Info: ALPN, offering http/1.1\n11:11:10.221901 http.c:664              == Info:  CAfile:\n/etc/ssl/certs/ca-certificates.crt\n11:11:10.221963 http.c:664              == Info:  CApath: none\n11:11:10.222300 http.c:664              == Info: TLSv1.3 (OUT), TLS\nhandshake, Client hello (1):\n11:11:10.233108 http.c:664              == Info: TLSv1.3 (IN), TLS\nhandshake, Server hello (2):\n11:11:10.233296 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Certificate (11):\n11:11:10.233803 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Server key exchange (12):\n11:11:10.233952 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Server finished (14):\n11:11:10.234129 http.c:664              == Info: TLSv1.2 (OUT), TLS\nhandshake, Client key exchange (16):\n11:11:10.234311 http.c:664              == Info: TLSv1.2 (OUT), TLS\nchange cipher, Change cipher spec (1):\n11:11:10.234429 http.c:664              == Info: TLSv1.2 (OUT), TLS\nhandshake, Finished (20):\n11:11:10.240556 http.c:664              == Info: TLSv1.2 (IN), TLS\nhandshake, Finished (20):\n11:11:10.240640 http.c:664              == Info: SSL connection using\nTLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256\n11:11:10.240655 http.c:664              == Info: ALPN, server accepted to use h2\n11:11:10.240705 http.c:664              == Info: Server certificate:\n11:11:10.240724 http.c:664              == Info:  subject: CN=*.xxx.xxx\n11:11:10.240743 http.c:664              == Info:  start date: Apr  8\n00:00:00 2022 GMT\n11:11:10.240751 http.c:664              == Info:  expire date: Apr  9\n23:59:59 2023 GMT\n11:11:10.240769 http.c:664              == Info:  subjectAltName: host\n\"xxx.xxx\" matched cert's \"*.xxx.xxx\"\n11:11:10.240792 http.c:664              == Info:  issuer: C=US;\nO=DigiCert Inc; CN=RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1\n11:11:10.240807 http.c:664              == Info:  SSL certificate verify ok.\n11:11:10.240873 http.c:664              == Info: Using HTTP2, server\nsupports multiplexing\n11:11:10.240912 http.c:664              == Info: Connection state\nchanged (HTTP/2 confirmed)\n11:11:10.240926 http.c:664              == Info: Copying HTTP/2 data\nin stream buffer to connection buffer after upgrade: len=0\n11:11:10.241310 http.c:664              == Info: Using Stream ID: 1\n(easy handle 0x7ff7c6f93ab0)\n11:11:10.241507 http.c:611              => Send header, 0000000219\nbytes (0x000000db)\n11:11:10.241539 http.c:623              => Send header: GET\n/xxx/xxx/info/refs?service=git-upload-pack HTTP/2\n11:11:10.241593 http.c:623              => Send header: Host: xxx.xxx\n11:11:10.241612 http.c:623              => Send header: user-agent: git/2.34.2\n11:11:10.241623 http.c:623              => Send header: accept: */*\n11:11:10.241632 http.c:623              => Send header:\naccept-encoding: deflate, gzip, br\n11:11:10.241642 http.c:623              => Send header: pragma: no-cache\n11:11:10.241653 http.c:623              => Send header: git-protocol: version=2\n11:11:10.241662 http.c:623              => Send header:\n11:11:10.241944 http.c:664              == Info: Connection state\nchanged (MAX_CONCURRENT_STREAMS == 128)!\n11:11:10.252717 http.c:611              <= Recv header, 0000000013\nbytes (0x0000000d)\n11:11:10.252792 http.c:623              <= Recv header: HTTP/2 401\n11:11:10.252811 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n11:11:10.252829 http.c:623              <= Recv header: date: Fri, 19\nAug 2022 11:11:10 GMT\n11:11:10.252849 http.c:611              <= Recv header, 0000000047\nbytes (0x0000002f)\n11:11:10.252863 http.c:623              <= Recv header: content-type:\napplication/json; charset=UTF-8\n11:11:10.252874 http.c:611              <= Recv header, 0000000020\nbytes (0x00000014)\n11:11:10.252887 http.c:623              <= Recv header: content-length: 69\n11:11:10.252938 http.c:611              <= Recv header, 0000000070\nbytes (0x00000046)\n11:11:10.252956 http.c:623              <= Recv header: traceparent:\n00-f423b7618abb5590f143da20b2febda1-e63b3c81e9e9dd7b-01\n11:11:10.252973 http.c:611              <= Recv header, 0000000042\nbytes (0x0000002a)\n11:11:10.252984 http.c:623              <= Recv header:\nwww-authenticate: Basic realm=Restricted\n11:11:10.253028 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n11:11:10.253036 http.c:623              <= Recv header:\n11:11:10.253050 http.c:664              == Info: Ignoring the response-body\n11:11:10.253439 http.c:664              == Info: Connection #1 to host\nxxx.xxx left intact\n11:11:10.253504 http.c:664              == Info: Issue another request\nto this URL: 'https://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack'\n11:11:10.253611 http.c:664              == Info: Found bundle for host\nxxx.xxx: 0x7ff7c6fbb590 [can multiplex]\n11:11:10.253679 http.c:664              == Info: Re-using existing\nconnection! (#1) with host xxx.xxx\n11:11:10.253783 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx) port 443 (#1)\n11:11:10.253856 http.c:664              == Info: Server auth using\nBasic with user 'git'\n11:11:10.253893 http.c:664              == Info: Using Stream ID: 3\n(easy handle 0x7ff7c6f93ab0)\n11:11:10.254109 http.c:611              => Send header, 0000000290\nbytes (0x00000122)\n11:11:10.254171 http.c:623              => Send header: GET\n/xxx/xxx/info/refs?service=git-upload-pack HTTP/2\n11:11:10.254184 http.c:623              => Send header: Host: xxx.xxx\n11:11:10.254276 http.c:623              => Send header: authorization: Basic\n11:11:10.254302 http.c:623              => Send header: user-agent: git/2.34.2\n11:11:10.254313 http.c:623              => Send header: accept: */*\n11:11:10.254325 http.c:623              => Send header:\naccept-encoding: deflate, gzip, br\n11:11:10.254343 http.c:623              => Send header: pragma: no-cache\n11:11:10.254356 http.c:623              => Send header: git-protocol: version=2\n11:11:10.254366 http.c:623              => Send header:\n11:11:10.326732 http.c:611              <= Recv header, 0000000013\nbytes (0x0000000d)\n11:11:10.326883 http.c:623              <= Recv header: HTTP/2 200\n11:11:10.326918 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n11:11:10.326943 http.c:623              <= Recv header: date: Fri, 19\nAug 2022 11:11:10 GMT\n11:11:10.326954 http.c:611              <= Recv header, 0000000059\nbytes (0x0000003b)\n11:11:10.326973 http.c:623              <= Recv header: content-type:\napplication/x-git-upload-pack-advertisement\n11:11:10.327000 http.c:611              <= Recv header, 0000000053\nbytes (0x00000035)\n11:11:10.327023 http.c:623              <= Recv header: cache-control:\nno-cache, max-age=0, must-revalidate\n11:11:10.327088 http.c:611              <= Recv header, 0000000040\nbytes (0x00000028)\n11:11:10.327114 http.c:623              <= Recv header: expires: Fri,\n01 Jan 1980 00:00:00 GMT\n11:11:10.327138 http.c:611              <= Recv header, 0000000018\nbytes (0x00000012)\n11:11:10.327149 http.c:623              <= Recv header: pragma: no-cache\n11:11:10.327164 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n11:11:10.327176 http.c:623              <= Recv header:\n11:11:10.327501 http.c:664              == Info: Connection #1 to host\nxxx.xxx left intact\nwarning: redirecting to https://xxx.xxx/xxx/xxx/\n11:11:10.328628 http.c:664              == Info: Found bundle for host\nxxx.xxx: 0x7ff7c6fbb590 [can multiplex]\n11:11:10.328730 http.c:664              == Info: Re-using existing\nconnection! (#1) with host xxx.xxx\n11:11:10.328845 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx) port 443 (#1)\n11:11:10.328899 http.c:664              == Info: Server auth using\nBasic with user 'git'\n11:11:10.328956 http.c:664              == Info: Using Stream ID: 5\n(easy handle 0x7ff7c6f93ab0)\n11:11:10.329168 http.c:611              => Send header, 0000000362\nbytes (0x0000016a)\n11:11:10.329286 http.c:623              => Send header: POST\n/xxx/xxx/git-upload-pack HTTP/2\n11:11:10.329305 http.c:623              => Send header: Host: xxx.xxx\n11:11:10.329313 http.c:623              => Send header: authorization: Basic\n11:11:10.329326 http.c:623              => Send header: user-agent: git/2.34.2\n11:11:10.329340 http.c:623              => Send header:\naccept-encoding: deflate, gzip, br\n11:11:10.329365 http.c:623              => Send header: content-type:\napplication/x-git-upload-pack-request\n11:11:10.329444 http.c:623              => Send header: accept:\napplication/x-git-upload-pack-result\n11:11:10.329485 http.c:623              => Send header: git-protocol: version=2\n11:11:10.329583 http.c:623              => Send header: content-length: 164\n11:11:10.329594 http.c:623              => Send header:\n11:11:10.329819 http.c:664              == Info: We are completely\nuploaded and fine\n11:11:10.447431 http.c:611              <= Recv header, 0000000013\nbytes (0x0000000d)\n11:11:10.447496 http.c:623              <= Recv header: HTTP/2 200\n11:11:10.447516 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n11:11:10.447524 http.c:623              <= Recv header: date: Fri, 19\nAug 2022 11:11:10 GMT\n11:11:10.447574 http.c:611              <= Recv header, 0000000052\nbytes (0x00000034)\n11:11:10.447591 http.c:623              <= Recv header: content-type:\napplication/x-git-upload-pack-result\n11:11:10.447639 http.c:611              <= Recv header, 0000000053\nbytes (0x00000035)\n11:11:10.447649 http.c:623              <= Recv header: cache-control:\nno-cache, max-age=0, must-revalidate\n11:11:10.447660 http.c:611              <= Recv header, 0000000040\nbytes (0x00000028)\n11:11:10.447670 http.c:623              <= Recv header: expires: Fri,\n01 Jan 1980 00:00:00 GMT\n11:11:10.447679 http.c:611              <= Recv header, 0000000018\nbytes (0x00000012)\n11:11:10.447687 http.c:623              <= Recv header: pragma: no-cache\n11:11:10.447701 http.c:611              <= Recv header, 0000000070\nbytes (0x00000046)\n11:11:10.447717 http.c:623              <= Recv header: traceparent:\n00-3134d9583a00d714098ad8db7a2f7777-10b2626d4765359f-01\n11:11:10.447727 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n11:11:10.447736 http.c:623              <= Recv header:\n11:11:10.662595 http.c:664              == Info: Connection #1 to host\nxxx.xxx left intact\n11:11:10.684884 http.c:664              == Info: Found bundle for host\nxxx.xxx: 0x7ff7c6fbb590 [can multiplex]\n11:11:10.684972 http.c:664              == Info: Re-using existing\nconnection! (#1) with host xxx.xxx\n11:11:10.685045 http.c:664              == Info: Connected to xxx.xxx\n(xxx.xxx.xxx) port 443 (#1)\n11:11:10.685122 http.c:664              == Info: Server auth using\nBasic with user 'git'\n11:11:10.685194 http.c:664              == Info: Using Stream ID: 7\n(easy handle 0x7ff7c6f93ab0)\n11:11:10.685431 http.c:611              => Send header, 0000000388\nbytes (0x00000184)\n11:11:10.685462 http.c:623              => Send header: POST\n/xxx/xxx/git-upload-pack HTTP/2\n11:11:10.685528 http.c:623              => Send header: Host: xxx.xxx\n11:11:10.685579 http.c:623              => Send header: authorization: Basic\n11:11:10.685597 http.c:623              => Send header: user-agent: git/2.34.2\n11:11:10.685636 http.c:623              => Send header:\naccept-encoding: deflate, gzip, br\n11:11:10.685671 http.c:623              => Send header: content-type:\napplication/x-git-upload-pack-request\n11:11:10.685685 http.c:623              => Send header: accept:\napplication/x-git-upload-pack-result\n11:11:10.685695 http.c:623              => Send header: git-protocol: version=2\n11:11:10.685704 http.c:623              => Send header: content-encoding: gzip\n11:11:10.685741 http.c:623              => Send header: content-length: 19678\n11:11:10.685945 http.c:623              => Send header:\n11:11:10.686431 http.c:664              == Info: We are completely\nuploaded and fine\n11:11:11.165227 http.c:611              <= Recv header, 0000000013\nbytes (0x0000000d)\n11:11:11.165334 http.c:623              <= Recv header: HTTP/2 200\n11:11:11.165358 http.c:611              <= Recv header, 0000000037\nbytes (0x00000025)\n11:11:11.165370 http.c:623              <= Recv header: date: Fri, 19\nAug 2022 11:11:11 GMT\n11:11:11.165391 http.c:611              <= Recv header, 0000000052\nbytes (0x00000034)\n11:11:11.165403 http.c:623              <= Recv header: content-type:\napplication/x-git-upload-pack-result\n11:11:11.165414 http.c:611              <= Recv header, 0000000053\nbytes (0x00000035)\n11:11:11.165430 http.c:623              <= Recv header: cache-control:\nno-cache, max-age=0, must-revalidate\n11:11:11.165490 http.c:611              <= Recv header, 0000000040\nbytes (0x00000028)\n11:11:11.165501 http.c:623              <= Recv header: expires: Fri,\n01 Jan 1980 00:00:00 GMT\n11:11:11.165518 http.c:611              <= Recv header, 0000000018\nbytes (0x00000012)\n11:11:11.165537 http.c:623              <= Recv header: pragma: no-cache\n11:11:11.165553 http.c:611              <= Recv header, 0000000070\nbytes (0x00000046)\n11:11:11.165582 http.c:623              <= Recv header: traceparent:\n00-8526084c5ce698fc4aaa4cd887c14e04-1ff731d1925ebf82-01\n11:11:11.165591 http.c:611              <= Recv header, 0000000002\nbytes (0x00000002)\n11:11:11.165628 http.c:623              <= Recv header:\nremote: Enumerating objects: 165, done.\nremote: Counting objects: 100% (165/165), done.\nremote: Compressing objects: 100% (162/162), done.\nremote: Total 45555 (delta 77), reused 0 (delta 0), pack-reused 45390\n11:11:17.236374 http.c:664              == Info: Connection #1 to host\nxxx.xxx left intact\nReceiving objects: 100% (45555/45555), 29.04 MiB | 4.85 MiB/s, done.\nResolving deltas: 100% (35362/35362), done.\n\nLook forward to your favourable reply！\n"},{"id":"461650","messageId":"YwCe6ONEaeIj4SO/@coredump.intra.peff.net","threadId":"58334","inReplyTo":"CADmGLV32OAg6HU+n1UsP2Fq-MjcyUsFFF=q0_jZCB0JEop5VUg@mail.gmail.com","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2022-08-20T08:44:24Z","receivedAt":"2022-08-20T08:44:31Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Aug 20, 2022 at 10:51:16AM +0800, 王小建 wrote:\n\n> What's different between what you expected and what actually happened?\n> \n> When I use git v2.36.2  (docker image is alpine/git:v2.36.2) to clone\n> with basic auth in url, when receiving the 401, it directly returns\n> authentication failure, even recv head has www-authenticate: Basic\n> realm=Restricted,\n> and no request is send again. I think it should send request with\n> authorization: Basic header after receive 401.\n> And use git v2.34.2 (docker image is alpine/git:v2.34.1) to clone it works well.\n\nI think the problem here is not the difference in Git versions, but\nrather in libcurl versions. I can reproduce your problem using the\ndocker containers. But if I build locally, using the same version of\ncurl, then I see the issue with both git versions.\n\nThe problem is how curl handles cross-protocol redirects. From Git's\nperspective, we hand the credentials to libcurl, and ask it to fetch the\nrequested URL, including following redirects. If it comes back with a\n401, then we assume our credentials were bad.\n\nBut what changed in curl is that it will now discard credentials during\na redirect. And in your example, there's a redirect from http to https\n(uninteresting bits snipped from the output):\n\n> Info: Connected to xxx.xxx (xxx.xxx.xxx.xxx) port 80 (#0)\n> Send header: GET /xxx/xxx/info/refs?service=git-upload-pack HTTP/1.1\n> Recv header: HTTP/1.1 302 Found\n> Recv header: Location: https://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack\n\nIn the older version, after the redirect we see a 401 and curl (not git)\nresends with the stored credentials.\n\nBut in the newer version, we see this right after the redirect:\n\n> Info: Connection #0 to host xxx.xxx left intact\n> Info: Clear auth, redirects to port from 80 to 443\n\nSo it is dropping the credential that Git gave it.\n\nThe curl change seems to be from 620ea2141 (transfer: redirects to other\nprotocols or ports clear auth, 2022-04-25). The goal is to avoid leaking\ncredentials between ports: https://curl.se/docs/CVE-2022-27774.html\n\nSo that makes sense, though I wonder if curl ought to make an exception\nfor moving from 80 to 443 and http to https?\n\nI don't think there's otherwise much Git can do here. We thought we gave\ncurl a username and password, but they weren't ultimately used. But Git\nwon't reissue the request, because it assumes the auth was rejected.\n\nI guess we can ask curl if it saw a redirect, and assume if so that the\nauth was cleared. That feels a bit hacky. And it's subverting curl's\nattempt not to leak the credentials. In general, I'd like to defer as\nmuch as possible to curl's ideas of how to handle things, because\nthey're much better at implementing http best practices than we are. :)\n\nAnother option is to allow the user to set CURLOPT_UNRESTRICTED_AUTH,\nbut that seems like a bad idea for the same reason.\n\nHopefully that explains what's going on. The short answer for your case\nis: use an https url directly, and it should work. But there's an open\nquestion of whether curl ought to handle this limited redirect case more\ngracefully.\n\n-Peff\n"},{"id":"461658","messageId":"CADmGLV2k9PGOMwS6zKwO6aY=aFJ7yvdgDkn8M2_XzPnEQkQQ0w@mail.gmail.com","threadId":"58334","inReplyTo":"YwCe6ONEaeIj4SO/@coredump.intra.peff.net","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"王小建","fromEmail":"littlejian8@gmail.com","sentAt":"2022-08-20T11:59:11Z","receivedAt":"2022-08-20T11:59:29Z","isPatch":false,"sender":{"key":"littlejian8@gmail.com","avatar":null},"body":"Thank you very much for your answer！\nNow I have a clear picture of what has been bothering me for a day.\nIndeed, use an https url directly, and it works well.\nNow I'm going to look into curl.\n\nJeff King <peff@peff.net> 于2022年8月20日周六 16:44写道：\n>\n> On Sat, Aug 20, 2022 at 10:51:16AM +0800, 王小建 wrote:\n>\n> > What's different between what you expected and what actually happened?\n> >\n> > When I use git v2.36.2  (docker image is alpine/git:v2.36.2) to clone\n> > with basic auth in url, when receiving the 401, it directly returns\n> > authentication failure, even recv head has www-authenticate: Basic\n> > realm=Restricted,\n> > and no request is send again. I think it should send request with\n> > authorization: Basic header after receive 401.\n> > And use git v2.34.2 (docker image is alpine/git:v2.34.1) to clone it works well.\n>\n> I think the problem here is not the difference in Git versions, but\n> rather in libcurl versions. I can reproduce your problem using the\n> docker containers. But if I build locally, using the same version of\n> curl, then I see the issue with both git versions.\n>\n> The problem is how curl handles cross-protocol redirects. From Git's\n> perspective, we hand the credentials to libcurl, and ask it to fetch the\n> requested URL, including following redirects. If it comes back with a\n> 401, then we assume our credentials were bad.\n>\n> But what changed in curl is that it will now discard credentials during\n> a redirect. And in your example, there's a redirect from http to https\n> (uninteresting bits snipped from the output):\n>\n> > Info: Connected to xxx.xxx (xxx.xxx.xxx.xxx) port 80 (#0)\n> > Send header: GET /xxx/xxx/info/refs?service=git-upload-pack HTTP/1.1\n> > Recv header: HTTP/1.1 302 Found\n> > Recv header: Location: https://xxx.xxx/xxx/xxx/info/refs?service=git-upload-pack\n>\n> In the older version, after the redirect we see a 401 and curl (not git)\n> resends with the stored credentials.\n>\n> But in the newer version, we see this right after the redirect:\n>\n> > Info: Connection #0 to host xxx.xxx left intact\n> > Info: Clear auth, redirects to port from 80 to 443\n>\n> So it is dropping the credential that Git gave it.\n>\n> The curl change seems to be from 620ea2141 (transfer: redirects to other\n> protocols or ports clear auth, 2022-04-25). The goal is to avoid leaking\n> credentials between ports: https://curl.se/docs/CVE-2022-27774.html\n>\n> So that makes sense, though I wonder if curl ought to make an exception\n> for moving from 80 to 443 and http to https?\n>\n> I don't think there's otherwise much Git can do here. We thought we gave\n> curl a username and password, but they weren't ultimately used. But Git\n> won't reissue the request, because it assumes the auth was rejected.\n>\n> I guess we can ask curl if it saw a redirect, and assume if so that the\n> auth was cleared. That feels a bit hacky. And it's subverting curl's\n> attempt not to leak the credentials. In general, I'd like to defer as\n> much as possible to curl's ideas of how to handle things, because\n> they're much better at implementing http best practices than we are. :)\n>\n> Another option is to allow the user to set CURLOPT_UNRESTRICTED_AUTH,\n> but that seems like a bad idea for the same reason.\n>\n> Hopefully that explains what's going on. The short answer for your case\n> is: use an https url directly, and it should work. But there's an open\n> question of whether curl ought to handle this limited redirect case more\n> gracefully.\n>\n> -Peff\n"},{"id":"461669","messageId":"o4sp3o6-75sp-o12o-2p29-r94s2s769r47@unkk.fr","threadId":"58334","inReplyTo":"YwCe6ONEaeIj4SO/@coredump.intra.peff.net","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"Daniel Stenberg","fromEmail":"daniel@haxx.se","sentAt":"2022-08-20T22:32:54Z","receivedAt":"2022-08-20T22:41:07Z","isPatch":false,"sender":{"key":"daniel@haxx.se","avatar":"https://gravatar.com/avatar/69fdca87edd17cee21ca2e79fc2ff671d644603c3dc27167430f3cd3dbab7ba8?d=mp&s=160"},"body":"On Sat, 20 Aug 2022, Jeff King wrote:\n\n> The curl change seems to be from 620ea2141 (transfer: redirects to other\n> protocols or ports clear auth, 2022-04-25). The goal is to avoid leaking\n> credentials between ports: https://curl.se/docs/CVE-2022-27774.html\n>\n> So that makes sense, though I wonder if curl ought to make an exception\n> for moving from 80 to 443 and http to https?\n\nNice research there Jeff, and yes this seems entirely correct.\n\nWe stopped curl from following such redirects because of the reasons stated in \nthe security advisory for that CVE. We quite simply realized that when curl \npreviously did that, it was actually doing more than what was documented and \nwhat can be considered reasonably safe.\n\nFollowing a redirect to another protocol and another port, even if it is still \non the same host name, might very well connect and use another server run by \nsomeone else than the one reached first. We therefore now consider that second \nhost+port+protocol combo a different host.\n\nSetting CURLOPT_UNRESTRICTED_AUTH is then the only way to make libcurl send \nthe credentials again after such a redirect.\n\nI would not mind having a discussion in the curl project to see if we should \npossibly consider adding a middle-ground where we allow sending credentials to \nanother port for the same host name, but I am personally NOT sold on the idea. \nI think such redirects should rather be fixed and avoided - since I believe \nusers will not understand the security implications of doing them.\n\n-- \n\n  / daniel.haxx.se\n"},{"id":"461742","messageId":"CADmGLV0F==7ep-xZKd2crZLi8JnFBFVkdX9Bi2T63NECcSAbVw@mail.gmail.com","threadId":"58334","inReplyTo":"o4sp3o6-75sp-o12o-2p29-r94s2s769r47@unkk.fr","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"王小建","fromEmail":"littlejian8@gmail.com","sentAt":"2022-08-22T03:35:10Z","receivedAt":"2022-08-22T03:35:29Z","isPatch":false,"sender":{"key":"littlejian8@gmail.com","avatar":null},"body":"Thank you very much for your answer！\nAnd now I tried to add CURLOPT_UNRESTRICTED_AUTH  but it failed.\nHere are a few examples of what I've tried.\n1. docker run -it -e CURLOPT_UNRESTRICTED_AUTH=1  5de1a96efc49  clone\nhttp://xxx:xxx@xxx/xxx/xxx\n2. echo CURLOPT_UNRESTRICTED_AUTH=1 > $HOME/.curlrc\nI wonder if it's the way I'm trying to do it wrong\n\nDaniel Stenberg <daniel@haxx.se> 于2022年8月21日周日 06:32写道：\n>\n> On Sat, 20 Aug 2022, Jeff King wrote:\n>\n> > The curl change seems to be from 620ea2141 (transfer: redirects to other\n> > protocols or ports clear auth, 2022-04-25). The goal is to avoid leaking\n> > credentials between ports: https://curl.se/docs/CVE-2022-27774.html\n> >\n> > So that makes sense, though I wonder if curl ought to make an exception\n> > for moving from 80 to 443 and http to https?\n>\n> Nice research there Jeff, and yes this seems entirely correct.\n>\n> We stopped curl from following such redirects because of the reasons stated in\n> the security advisory for that CVE. We quite simply realized that when curl\n> previously did that, it was actually doing more than what was documented and\n> what can be considered reasonably safe.\n>\n> Following a redirect to another protocol and another port, even if it is still\n> on the same host name, might very well connect and use another server run by\n> someone else than the one reached first. We therefore now consider that second\n> host+port+protocol combo a different host.\n>\n> Setting CURLOPT_UNRESTRICTED_AUTH is then the only way to make libcurl send\n> the credentials again after such a redirect.\n>\n> I would not mind having a discussion in the curl project to see if we should\n> possibly consider adding a middle-ground where we allow sending credentials to\n> another port for the same host name, but I am personally NOT sold on the idea.\n> I think such redirects should rather be fixed and avoided - since I believe\n> users will not understand the security implications of doing them.\n>\n> --\n>\n>   / daniel.haxx.se\n"},{"id":"461747","messageId":"YwNGoqcx3c27XpQL@coredump.intra.peff.net","threadId":"58334","inReplyTo":"o4sp3o6-75sp-o12o-2p29-r94s2s769r47@unkk.fr","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2022-08-22T09:04:34Z","receivedAt":"2022-08-22T09:04:41Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 21, 2022 at 12:32:54AM +0200, Daniel Stenberg wrote:\n\n> I would not mind having a discussion in the curl project to see if we should\n> possibly consider adding a middle-ground where we allow sending credentials\n> to another port for the same host name, but I am personally NOT sold on the\n> idea. I think such redirects should rather be fixed and avoided - since I\n> believe users will not understand the security implications of doing them.\n\nI'm not 100% on it either. When it comes to security restrictions,\nsometimes simple-and-stupid is the best way. I was literally thinking of\nsomething as basic and restricted as:\n\n  if (from_port == 80 && to_port == 443 &&\n      from_protocol == HTTP && to_protocol == HTTPS)\n        /* ok, allow it */\n\njust because https upgrade is such a common (and presumably harmless)\nredirect.  But possibly even that leaves wiggle room for bad things to\nhappen. I'm happy to defer to you and other curl folks there.\n\nI think the worst thing about the user experience from Git here is that\nit says \"authentication failed\", which is indistinguishable from a bogus\ncredential. We don't even mention the redirect, because we don't warn\nabout them unless the request ends up successful!\n\nSo I was thinking that curl could tell us \"hey, I cleared the auth due\nto a redirect\" via some curl_easy_getinfo() call. But maybe just\nnoticing there was a redirect would be sufficient. This seems to work:\n\ndiff --git a/http.c b/http.c\nindex 5d0502f51f..0fe8a906e5 100644\n--- a/http.c\n+++ b/http.c\n@@ -1934,7 +1934,7 @@ static int http_request_reauth(const char *url,\n {\n \tint ret = http_request(url, result, target, options);\n \n-\tif (ret != HTTP_OK && ret != HTTP_REAUTH)\n+\tif (ret != HTTP_OK && ret != HTTP_REAUTH && ret != HTTP_NOAUTH)\n \t\treturn ret;\n \n \tif (options && options->effective_url && options->base_url) {\ndiff --git a/remote-curl.c b/remote-curl.c\nindex b8758757ec..d462077a97 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -501,6 +501,12 @@ static struct discovery *discover_refs(const char *service, int for_push)\n \t\t    transport_anonymize_url(url.buf));\n \tcase HTTP_NOAUTH:\n \t\tshow_http_message(&type, &charset, &buffer);\n+\t\tif (LIBCURL_VERSION_NUM >= 0x075300 &&\n+\t\t    strcmp(refs_url.buf, effective_url.buf)) {\n+\t\t\tchar *u = transport_anonymize_url(url.buf);\n+\t\t\twarning(_(\"request redirected to %s\"), u);\n+\t\t\twarning(_(\"authentication information may have been discarded\"));\n+\t\t}\n \t\tdie(_(\"Authentication failed for '%s'\"),\n \t\t    transport_anonymize_url(url.buf));\n \tcase HTTP_NOMATCHPUBLICKEY:\n\nThough I wonder if there is a cleaner way to determine what happened\nthan string comparisons.\n\n-Peff\n"},{"id":"461748","messageId":"YwNHVfvb10VD2ROe@coredump.intra.peff.net","threadId":"58334","inReplyTo":"CADmGLV0F==7ep-xZKd2crZLi8JnFBFVkdX9Bi2T63NECcSAbVw@mail.gmail.com","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2022-08-22T09:07:33Z","receivedAt":"2022-08-22T09:07:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 22, 2022 at 11:35:10AM +0800, 王小建 wrote:\n\n> Thank you very much for your answer！\n> And now I tried to add CURLOPT_UNRESTRICTED_AUTH  but it failed.\n> Here are a few examples of what I've tried.\n> 1. docker run -it -e CURLOPT_UNRESTRICTED_AUTH=1  5de1a96efc49  clone\n> http://xxx:xxx@xxx/xxx/xxx\n> 2. echo CURLOPT_UNRESTRICTED_AUTH=1 > $HOME/.curlrc\n> I wonder if it's the way I'm trying to do it wrong\n\nThat won't work. CURLOPT_UNRESTRICTED_AUTH isn't an environment\nvariable, but rather a flag that Git could pass to libcurl via\ncurl_easy_setopt(). So we'd probably wire it up in Git to a config\noption. I'd prefer not to unless there is a compelling reason, though.\nThe documentation would have to come with a big warning/disclaimer,\nwhich is a good sign that we may be better off without the option\nentirely. :)\n\n-Peff\n"},{"id":"461816","messageId":"YwP/EYTwHbA14AZV@tapette.crustytoothpaste.net","threadId":"58334","inReplyTo":"YwNGoqcx3c27XpQL@coredump.intra.peff.net","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2022-08-22T22:11:29Z","receivedAt":"2022-08-22T22:11:35Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2022-08-22 at 09:04:34, Jeff King wrote:\n> On Sun, Aug 21, 2022 at 12:32:54AM +0200, Daniel Stenberg wrote:\n> \n> > I would not mind having a discussion in the curl project to see if we should\n> > possibly consider adding a middle-ground where we allow sending credentials\n> > to another port for the same host name, but I am personally NOT sold on the\n> > idea. I think such redirects should rather be fixed and avoided - since I\n> > believe users will not understand the security implications of doing them.\n> \n> I'm not 100% on it either. When it comes to security restrictions,\n> sometimes simple-and-stupid is the best way. I was literally thinking of\n> something as basic and restricted as:\n> \n>   if (from_port == 80 && to_port == 443 &&\n>       from_protocol == HTTP && to_protocol == HTTPS)\n>         /* ok, allow it */\n> \n> just because https upgrade is such a common (and presumably harmless)\n> redirect.  But possibly even that leaves wiggle room for bad things to\n> happen. I'm happy to defer to you and other curl folks there.\n\nI think it's actually better to fail in this case, and here's why.  If\nsomeone is using HTTP and getting redirected to HTTPS, there's no\nsecurity if an attacker intercepts the HTTP connection.  Anyone who\nknows how a captive portal works will recognize this immediately, and\nit's why we have Strict Transport Security in browsers.\n\nIf we fail when a user redirects, then they'll fix their URL to use\nHTTPS, at which point their connection is prevented from tampering\neffectively forever.  If we redirect, then when they make a connection,\nthey'll be vulnerable to tampering every time, possibly sending\ncredentials over the wire in plaintext or being redirected to a rogue\nsite.\n-- \nbrian m. carlson (he/him or they/them)\nToronto, Ontario, CA\n"},{"id":"461878","messageId":"YwU1uuaeV2s7a2+C@coredump.intra.peff.net","threadId":"58334","inReplyTo":"YwP/EYTwHbA14AZV@tapette.crustytoothpaste.net","subject":"Re: git clone with basic auth in url directly returns authentication failure after 401 received under some git versions","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2022-08-23T20:16:58Z","receivedAt":"2022-08-23T20:36:01Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 22, 2022 at 10:11:29PM +0000, brian m. carlson wrote:\n\n> > I'm not 100% on it either. When it comes to security restrictions,\n> > sometimes simple-and-stupid is the best way. I was literally thinking of\n> > something as basic and restricted as:\n> > \n> >   if (from_port == 80 && to_port == 443 &&\n> >       from_protocol == HTTP && to_protocol == HTTPS)\n> >         /* ok, allow it */\n> > \n> > just because https upgrade is such a common (and presumably harmless)\n> > redirect.  But possibly even that leaves wiggle room for bad things to\n> > happen. I'm happy to defer to you and other curl folks there.\n> \n> I think it's actually better to fail in this case, and here's why.  If\n> someone is using HTTP and getting redirected to HTTPS, there's no\n> security if an attacker intercepts the HTTP connection.  Anyone who\n> knows how a captive portal works will recognize this immediately, and\n> it's why we have Strict Transport Security in browsers.\n> \n> If we fail when a user redirects, then they'll fix their URL to use\n> HTTPS, at which point their connection is prevented from tampering\n> effectively forever.  If we redirect, then when they make a connection,\n> they'll be vulnerable to tampering every time, possibly sending\n> credentials over the wire in plaintext or being redirected to a rogue\n> site.\n\nI agree redirecting is less secure, but in this case the credentials are\ncleared unless it's an http->https upgrade on the same hostname (not\nshown in my example above is the implication that curl would still be\ndoing the hostname check).\n\nWe also follow redirects in general, so this is just about clearing\nin-url credentials. We'll still prompt for credentials in the more usual\ncase, though we do properly say \"password for $REDIRECTED_URL\" when\ndoing so.\n\nAll that said, I agree that failing and asking the user to adjust their\nURL is a fine outcome, as long as we do that. The problem now is just\nthat Git's output is misleading at best. The diff I showed earlier would\nhelp with that. I think it could use a little polish, but I'll see if I\ncan do that in the next few days.\n\n-Peff\n"}]}