From d5e83eb745762f48d8fafadc5df5dd3ae8d8941e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Apr 2024 11:32:55 +0200 Subject: [PATCH] url: do not URL decode proxy crendentials The two options CURLOPT_PROXYUSERNAME and CURLOPT_PROXYPASSWORD set the actual names as-is, not URL encoded. Modified test 503 to use percent-encoded strings in the credential strings that should be passed on as-is. Reported-by: Sergey Ogryzkov Fixes #13265 Closes #13270 --- lib/setopt.c | 21 +++++++++++++++++---- lib/url.c | 21 ++++++++++----------- tests/data/test503 | 2 +- tests/libtest/lib503.c | 3 ++- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/lib/setopt.c b/lib/setopt.c index 8a5a5d7c33..f6365bd90a 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -52,6 +52,8 @@ #include "hsts.h" #include "tftp.h" #include "strdup.h" +#include "escape.h" + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -1593,13 +1595,24 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXYUSERPWD: + case CURLOPT_PROXYUSERPWD: { /* * user:password needed to use the proxy */ - result = setstropt_userpwd(va_arg(param, char *), - &data->set.str[STRING_PROXYUSERNAME], - &data->set.str[STRING_PROXYPASSWORD]); + char *u = NULL; + char *p = NULL; + result = setstropt_userpwd(va_arg(param, char *), &u, &p); + + /* URL decode the components */ + if(!result && u) + result = Curl_urldecode(u, 0, &data->set.str[STRING_PROXYUSERNAME], NULL, + REJECT_ZERO); + if(!result && p) + result = Curl_urldecode(p, 0, &data->set.str[STRING_PROXYPASSWORD], NULL, + REJECT_ZERO); + free(u); + free(p); + } break; case CURLOPT_PROXYUSERNAME: /* diff --git a/lib/url.c b/lib/url.c index 224b9f3e2b..549e8f91fb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2366,17 +2366,16 @@ static CURLcode parse_proxy_auth(struct Curl_easy *data, data->state.aptr.proxyuser : ""; const char *proxypasswd = data->state.aptr.proxypasswd ? data->state.aptr.proxypasswd : ""; - CURLcode result = Curl_urldecode(proxyuser, 0, &conn->http_proxy.user, NULL, - REJECT_ZERO); - if(!result) - result = Curl_setstropt(&data->state.aptr.proxyuser, - conn->http_proxy.user); - if(!result) - result = Curl_urldecode(proxypasswd, 0, &conn->http_proxy.passwd, - NULL, REJECT_ZERO); - if(!result) - result = Curl_setstropt(&data->state.aptr.proxypasswd, - conn->http_proxy.passwd); + CURLcode result = CURLE_OUT_OF_MEMORY; + + conn->http_proxy.user = strdup(proxyuser); + if(conn->http_proxy.user) { + conn->http_proxy.passwd = strdup(proxypasswd); + if(conn->http_proxy.passwd) + result = CURLE_OK; + else + Curl_safefree(conn->http_proxy.user); + } return result; } diff --git a/tests/data/test503 b/tests/data/test503 index 0690ad3407..9fbc00b951 100644 --- a/tests/data/test503 +++ b/tests/data/test503 @@ -73,7 +73,7 @@ moo CONNECT machine.%TESTNUMBER:%HTTPPORT HTTP/1.1 Host: machine.%TESTNUMBER:%HTTPPORT -Proxy-Authorization: Basic dGVzdDppbmc= +Proxy-Authorization: Basic dGVzdCUyMDppbmclNDE= Proxy-Connection: Keep-Alive [DISCONNECT] diff --git a/tests/libtest/lib503.c b/tests/libtest/lib503.c index 15b09476e3..c3ea2fc5f8 100644 --- a/tests/libtest/lib503.c +++ b/tests/libtest/lib503.c @@ -53,7 +53,8 @@ int test(char *URL) easy_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */ easy_setopt(c, CURLOPT_URL, URL); easy_setopt(c, CURLOPT_USERPWD, "test:ing"); - easy_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing"); + easy_setopt(c, CURLOPT_PROXYUSERNAME, "test%20"); + easy_setopt(c, CURLOPT_PROXYPASSWORD, "ing%41"); easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L); easy_setopt(c, CURLOPT_HEADER, 1L); easy_setopt(c, CURLOPT_VERBOSE, 1L); -- 2.47.3