Skip to content

Commit b4024bf

Browse files
committed
http: clear credentials better on redirect
Verify with test 2506: netrc with redirect using proxy Updated test 998 which was wrong. Reported-by: Muhamad Arga Reksapati Closes #21345
1 parent 3e0e2cc commit b4024bf

6 files changed

Lines changed: 162 additions & 62 deletions

File tree

lib/http.c

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,75 +1227,41 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
12271227
return CURLE_OUT_OF_MEMORY;
12281228
}
12291229
else {
1230-
uc = curl_url_get(data->state.uh, CURLUPART_URL, &follow_url, 0);
1231-
if(uc)
1230+
bool same_origin;
1231+
CURLcode result;
1232+
CURLU *u = curl_url();
1233+
if(!u)
1234+
return CURLE_OUT_OF_MEMORY;
1235+
uc = curl_url_set(u, CURLUPART_URL,
1236+
Curl_bufref_ptr(&data->state.url),
1237+
CURLU_URLENCODE | CURLU_ALLOW_SPACE);
1238+
if(!uc)
1239+
uc = curl_url_get(data->state.uh, CURLUPART_URL, &follow_url, 0);
1240+
if(uc) {
1241+
curl_url_cleanup(u);
12321242
return Curl_uc_to_curlcode(uc);
1243+
}
12331244

1234-
/* Clear auth if this redirects to a different port number or protocol,
1235-
unless permitted */
1236-
if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
1237-
uint16_t port;
1238-
bool clear = FALSE;
1239-
1240-
if(data->set.use_port && data->state.allow_port)
1241-
/* a custom port is used */
1242-
port = data->set.use_port;
1243-
else {
1244-
curl_off_t value;
1245-
char *portnum;
1246-
const char *p;
1247-
uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum,
1248-
CURLU_DEFAULT_PORT);
1249-
if(uc) {
1250-
curlx_free(follow_url);
1251-
return Curl_uc_to_curlcode(uc);
1252-
}
1253-
p = portnum;
1254-
curlx_str_number(&p, &value, 0xffff);
1255-
port = (uint16_t)value;
1256-
curlx_free(portnum);
1257-
}
1258-
if(port != data->info.conn_remote_port) {
1259-
infof(data, "Clear auth, redirects to port from %d to %d",
1260-
data->info.conn_remote_port, port);
1261-
clear = TRUE;
1262-
}
1263-
else {
1264-
char *scheme;
1265-
const struct Curl_scheme *p;
1266-
uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
1267-
if(uc) {
1268-
curlx_free(follow_url);
1269-
return Curl_uc_to_curlcode(uc);
1270-
}
1245+
same_origin = Curl_url_same_origin(u, data->state.uh);
1246+
curl_url_cleanup(u);
12711247

1272-
p = Curl_get_scheme(scheme);
1273-
if(p && (p->protocol != data->info.conn_protocol)) {
1274-
infof(data, "Clear auth, redirects scheme from %s to %s",
1275-
data->info.conn_scheme, scheme);
1276-
clear = TRUE;
1277-
}
1278-
curlx_free(scheme);
1279-
}
1280-
if(clear) {
1281-
CURLcode result = Curl_reset_userpwd(data);
1282-
if(result) {
1283-
curlx_free(follow_url);
1284-
return result;
1285-
}
1286-
curlx_safefree(data->state.aptr.user);
1287-
curlx_safefree(data->state.aptr.passwd);
1248+
if((!same_origin && !data->set.allow_auth_to_other_hosts) ||
1249+
!data->set.str[STRING_USERNAME]) {
1250+
result = Curl_reset_userpwd(data);
1251+
if(result) {
1252+
curlx_free(follow_url);
1253+
return result;
12881254
}
1255+
curlx_safefree(data->state.aptr.user);
1256+
curlx_safefree(data->state.aptr.passwd);
12891257
}
1290-
}
1291-
DEBUGASSERT(follow_url);
1292-
{
1293-
CURLcode result = Curl_reset_proxypwd(data);
1258+
result = Curl_reset_proxypwd(data);
12941259
if(result) {
12951260
curlx_free(follow_url);
12961261
return result;
12971262
}
12981263
}
1264+
DEBUGASSERT(follow_url);
12991265

13001266
if(type == FOLLOW_FAKE) {
13011267
/* we are only figuring out the new URL if we would have followed locations

tests/data/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ test2309 \
265265
\
266266
test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 \
267267
\
268-
test2500 test2501 test2502 test2503 test2504 test2505 \
268+
test2500 test2501 test2502 test2503 test2504 test2505 test2506 \
269269
\
270270
test2600 test2601 test2602 test2603 test2604 test2605 \
271271
\

tests/data/test2506

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?xml version="1.0" encoding="US-ASCII"?>
2+
<testcase>
3+
<info>
4+
<keywords>
5+
HTTP
6+
cookies
7+
</keywords>
8+
</info>
9+
10+
<reply>
11+
<data crlf="headers" nocheck="yes">
12+
HTTP/1.1 301 redirect
13+
Date: Tue, 09 Nov 2010 14:49:00 GMT
14+
Content-Length: 3
15+
Location: http://numbertwo.example/%TESTNUMBER0002
16+
17+
ok
18+
</data>
19+
<data2 crlf="headers" nocheck="yes">
20+
HTTP/1.1 200 OK
21+
Date: Tue, 09 Nov 2010 14:49:00 GMT
22+
Content-Length: 4
23+
24+
yes
25+
</data2>
26+
</reply>
27+
28+
<client>
29+
<server>
30+
http
31+
</server>
32+
<features>
33+
proxy
34+
</features>
35+
<tool>
36+
lib%TESTNUMBER
37+
</tool>
38+
<name>
39+
netrc with redirect using proxy
40+
</name>
41+
<file name="%LOGDIR/netrc2506">
42+
machine site.example login batman password robin
43+
</file>
44+
<command>
45+
http://%HOSTIP:%HTTPPORT http://site.example/ %LOGDIR/netrc2506
46+
</command>
47+
</client>
48+
49+
<verify>
50+
<protocol crlf="headers">
51+
GET http://site.example/ HTTP/1.1
52+
Host: site.example
53+
Authorization: Basic %b64[batman:robin]b64%
54+
Accept: */*
55+
Proxy-Connection: Keep-Alive
56+
57+
GET http://numbertwo.example/25060002 HTTP/1.1
58+
Host: numbertwo.example
59+
Accept: */*
60+
Proxy-Connection: Keep-Alive
61+
62+
</protocol>
63+
</verify>
64+
</testcase>

tests/data/test998

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ Proxy-Connection: Keep-Alive
7777

7878
GET http://somewhere.else.example/a/path/9980002 HTTP/1.1
7979
Host: somewhere.else.example
80-
Authorization: Basic %b64[alberto:einstein]b64%
8180
User-Agent: curl/%VERSION
8281
Accept: */*
8382
Proxy-Connection: Keep-Alive

tests/libtest/Makefile.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ TESTS_C = \
112112
lib2023.c lib2032.c lib2082.c \
113113
lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c \
114114
lib2402.c lib2404.c lib2405.c \
115-
lib2502.c lib2504.c lib2505.c \
115+
lib2502.c lib2504.c lib2505.c lib2506.c \
116116
lib2700.c \
117117
lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c \
118118
lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c \

tests/libtest/lib2506.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/***************************************************************************
2+
* _ _ ____ _
3+
* Project ___| | | | _ \| |
4+
* / __| | | | |_) | |
5+
* | (__| |_| | _ <| |___
6+
* \___|\___/|_| \_\_____|
7+
*
8+
* Copyright (C) Linus Nielsen Feltzing <linus@haxx.se>
9+
*
10+
* This software is licensed as described in the file COPYING, which
11+
* you should have received as part of this distribution. The terms
12+
* are also available at https://curl.se/docs/copyright.html.
13+
*
14+
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
* copies of the Software, and permit persons to whom the Software is
16+
* furnished to do so, under the terms of the COPYING file.
17+
*
18+
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
* KIND, either express or implied.
20+
*
21+
* SPDX-License-Identifier: curl
22+
*
23+
***************************************************************************/
24+
#include "first.h"
25+
26+
#include "testtrace.h"
27+
28+
static size_t sink2506(char *ptr, size_t size, size_t nmemb, void *ud)
29+
{
30+
(void)ptr;
31+
(void)ud;
32+
return size * nmemb;
33+
}
34+
35+
static CURLcode test_lib2506(const char *URL)
36+
{
37+
CURL *curl;
38+
CURLcode result = CURLE_OUT_OF_MEMORY;
39+
40+
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
41+
curl_mfprintf(stderr, "curl_global_init() failed\n");
42+
return TEST_ERR_MAJOR_BAD;
43+
}
44+
45+
curl = curl_easy_init();
46+
if(!curl) {
47+
curl_mfprintf(stderr, "curl_easy_init() failed\n");
48+
curl_global_cleanup();
49+
return TEST_ERR_MAJOR_BAD;
50+
}
51+
52+
test_setopt(curl, CURLOPT_WRITEFUNCTION, sink2506);
53+
test_setopt(curl, CURLOPT_PROXY, URL);
54+
test_setopt(curl, CURLOPT_URL, libtest_arg2);
55+
test_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
56+
test_setopt(curl, CURLOPT_NETRC_FILE, libtest_arg3);
57+
test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
58+
test_setopt(curl, CURLOPT_VERBOSE, 1L);
59+
60+
/* CURLOPT_UNRESTRICTED_AUTH should not make a difference because the
61+
credentials come from netrc */
62+
test_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L);
63+
64+
result = curl_easy_perform(curl);
65+
66+
test_cleanup:
67+
curl_easy_cleanup(curl);
68+
curl_global_cleanup();
69+
70+
return result;
71+
}

0 commit comments

Comments
 (0)