1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-11 20:15:03 -05:00

transfer: strip credentials from the auto-referer header field

Added test 2081 to verify.

CVE-2021-22876

Bug: https://curl.se/docs/CVE-2021-22876.html
This commit is contained in:
Viktor Szakats 2021-02-23 14:54:46 +01:00 committed by Daniel Stenberg
parent 184ffc0bdf
commit 7214288898
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 90 additions and 3 deletions

View File

@ -1581,6 +1581,9 @@ CURLcode Curl_follow(struct Curl_easy *data,
data->state.followlocation++; /* count location-followers */ data->state.followlocation++; /* count location-followers */
if(data->set.http_auto_referer) { if(data->set.http_auto_referer) {
CURLU *u;
char *referer;
/* We are asked to automatically set the previous URL as the referer /* We are asked to automatically set the previous URL as the referer
when we get the next URL. We pick the ->url field, which may or may when we get the next URL. We pick the ->url field, which may or may
not be 100% correct */ not be 100% correct */
@ -1590,9 +1593,27 @@ CURLcode Curl_follow(struct Curl_easy *data,
data->state.referer_alloc = FALSE; data->state.referer_alloc = FALSE;
} }
data->state.referer = strdup(data->state.url); /* Make a copy of the URL without crenditals and fragment */
if(!data->state.referer) u = curl_url();
if(!u)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0);
if(!uc)
uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0);
if(!uc)
uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
if(!uc)
uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
if(!uc)
uc = curl_url_get(u, CURLUPART_URL, &referer, 0);
curl_url_cleanup(u);
if(uc || referer == NULL)
return CURLE_OUT_OF_MEMORY;
data->state.referer = referer;
data->state.referer_alloc = TRUE; /* yes, free this later */ data->state.referer_alloc = TRUE; /* yes, free this later */
} }
} }

View File

@ -225,7 +225,7 @@ test2064 test2065 test2066 test2067 test2068 test2069 \
test2064 test2065 test2066 test2067 test2068 test2069 test2070 \ test2064 test2065 test2066 test2067 test2068 test2069 test2070 \
test2071 test2072 test2073 test2074 test2075 test2076 test2077 \ test2071 test2072 test2073 test2074 test2075 test2076 test2077 \
test2078 \ test2078 \
test2080 \ test2080 test2081 \
test2100 \ test2100 \
\ \
test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \ test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \

66
tests/data/test2081 Normal file
View File

@ -0,0 +1,66 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
referer
followlocation
--write-out
</keywords>
</info>
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 301 This is a weirdo text message swsclose
Location: data/%TESTNUMBER0002.txt?coolsite=yes
Content-Length: 62
Connection: close
This server reply is for testing a simple Location: following
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
<name>
Automatic referrer credential and anchor stripping check
</name>
<command>
http://user:pass@%HOSTIP:%HTTPPORT/we/want/our/%TESTNUMBER#anchor --location --referer ';auto' --write-out '%{referer}\n'
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<errorcode>
52
</errorcode>
<protocol>
GET /we/want/our/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpwYXNz
User-Agent: curl/%VERSION
Accept: */*
GET /we/want/our/data/%TESTNUMBER0002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpwYXNz
User-Agent: curl/%VERSION
Accept: */*
Referer: http://%HOSTIP:%HTTPPORT/we/want/our/%TESTNUMBER
</protocol>
<stdout>
HTTP/1.1 301 This is a weirdo text message swsclose
Location: data/%TESTNUMBER0002.txt?coolsite=yes
Content-Length: 62
Connection: close
http://%HOSTIP:%HTTPPORT/we/want/our/%TESTNUMBER
</stdout>
</verify>
</testcase>