url: reject control codes in credentials set via CURLOPT

Closes #22236
This commit is contained in:
Alhuda Khan 2026-07-01 15:11:15 +05:30 committed by Daniel Stenberg
parent 69ac867f98
commit ecaa344a7a
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 55 additions and 2 deletions

View file

@ -1398,7 +1398,6 @@ static CURLcode hsts_upgrade(struct Curl_easy *data,
#define hsts_upgrade(x, y, z, a) CURLE_OK
#endif
#ifndef CURL_DISABLE_NETRC
static bool str_has_ctrl(const char *input)
{
if(input) {
@ -1412,6 +1411,7 @@ static bool str_has_ctrl(const char *input)
return FALSE;
}
#ifndef CURL_DISABLE_NETRC
/*
* Override the login details from the URL with that in the CURLOPT_USERPWD
* option or a .netrc file, if applicable.
@ -1538,6 +1538,16 @@ static CURLcode url_set_data_creds(struct Curl_easy *data, CURLU *uh)
CREDS_OPTION, &newcreds);
if(result)
goto out;
if(newcreds &&
!(data->state.origin->scheme->flags & PROTOPT_USERPWDCTRL) &&
(str_has_ctrl(Curl_creds_user(newcreds)) ||
str_has_ctrl(Curl_creds_passwd(newcreds)))) {
/* if the protocol cannot handle control codes in credentials, make
sure there are none */
failf(data, "control code detected in credentials");
result = CURLE_BAD_FUNCTION_ARGUMENT;
goto out;
}
}
/* Extract credentials from the URL only if there are none OR

View file

@ -254,7 +254,7 @@ test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 \
test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 \
test2088 test2089 test2090 test2091 test2092 \
test2100 test2101 test2102 test2103 test2104 test2105 test2106 test2107 \
test2108 test2109 test2110 test2113 \
test2108 test2109 test2110 test2113 test2114 \
\
test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 \
test2208 \

43
tests/data/test2114 Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="US-ASCII"?>
<testcase>
<info>
<keywords>
FTP
</keywords>
</info>
# Server-side
<reply>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP username with embedded CRLF is rejected
</name>
# read the credentials from a config file so the raw CR LF reaches curl intact
# regardless of how the platform passes command line arguments
<file name="%LOGDIR/test%TESTNUMBER.config">
user = "anonymous\r\nSTOR /%TESTNUMBER"
</file>
<command>
ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -K %LOGDIR/test%TESTNUMBER.config
</command>
</client>
# Verify data after the test has been "shot"
<verify>
# 43 - CURLE_BAD_FUNCTION_ARGUMENT
<errorcode>
43
</errorcode>
# the credentials are rejected before connecting so the injected STOR command
# must never reach the server
<protocol nonewline="yes">
</protocol>
</verify>
</testcase>