From 826e8011d5417504fcd4b7c2769bf47e97768788 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 9 Apr 2023 00:38:00 +0200 Subject: [PATCH] urlapi: prevent setting invalid schemes with *url_set() A typical mistake would be to try to set "https://" - including the separator - this is now rejected as that would then lead to url_get(... URL...) would get an invalid URL extracted. Extended test 1560 to verify. Closes #10911 --- lib/urlapi.c | 16 +++++++++++++--- tests/libtest/lib1560.c | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/urlapi.c b/lib/urlapi.c index ece4c4868..520cab319 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -1728,9 +1728,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } switch(what) { - case CURLUPART_SCHEME: - if(strlen(part) > MAX_SCHEME_LEN) - /* too long */ + case CURLUPART_SCHEME: { + size_t plen = strlen(part); + const char *s = part; + if((plen > MAX_SCHEME_LEN) || (plen < 1)) + /* too long or too short */ return CURLUE_BAD_SCHEME; if(!(flags & CURLU_NON_SUPPORT_SCHEME) && /* verify that it is a fine scheme */ @@ -1738,7 +1740,15 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, return CURLUE_UNSUPPORTED_SCHEME; storep = &u->scheme; urlencode = FALSE; /* never */ + /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ + while(plen--) { + if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.')) + s++; /* fine */ + else + return CURLUE_BAD_SCHEME; + } break; + } case CURLUPART_USER: storep = &u->user; break; diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index aba084162..fe763b1ce 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -712,6 +712,11 @@ static const struct setcase set_parts_list[] = { CURLU_URLENCODE, /* encode on set */ CURLUE_OK, CURLUE_OK}, + {"https://example.com/", + /* Set a bad scheme *including* :// */ + "scheme=https://,", + "https://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, {"https://example.com/", /* Set a 41 bytes scheme. That's too long so the old scheme remains set. */ "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,",