HexBrain

curl · Report #3736234

NULL pointer dereference in libcurl URL API redirect_url() with CURLU_DEFAULT_SCHEME

Informativestatus
5upvotes
17 May 2026disclosed

How it was found

Summary A NULL pointer dereference appears to exist in libcurl's URL API path when curl_url_set() handles a relative URL together with CURLU_DEFAULT_SCHEME on a CURLU handle that has host/path information but no stored u->scheme. The issue is in lib/urlapi.c inside redirect_url(), where u->scheme is used in strlen(u->scheme) before the function checks whether the relevant inputs are valid. If the URL handle reaches this path without a stored scheme, the process can crash with SIGSEGV. Dan Fandrich from the curl security list asked me to submit this report on HackerOne for tracking. This is the same issue previously emailed to [email protected]. ## Affected version - Source reviewed: curl master / 8.21.0-DEV area, lib/urlapi.c, redirect_url() - The original report stated reproduction against libcurl 8.14.1 and the current development source path. - Local reproduction environment used libcurl URL API semantics around CURLU_DEFAULT_SCHEME. ## Technical details In redirect_url(), u->scheme is dereferenced before a safe NULL check: c const char *protsep = base + strlen(u->scheme) + 3; DEBUGASSERT(base && relurl && u); if(!base) return CURLUE_MALFORMED_INPUT; The problematic path is possible because urlget_url() can use DEFAULT_SCHEME locally when CURLU_DEFAULT_SCHEME is supplied, without necessarily storing a scheme in u->scheme: c if(u->scheme) scheme = u->scheme; else if(flags & CURLU_DEFAULT_SCHEME) scheme = DEFAULT_SCHEME; else return CURLUE_NO_SCHEME; This means URL generation can succeed using a default scheme string, while the underlying CURLU object can still have u->scheme == NULL. Later, redirect_url() assumes u->scheme is non-NULL and calls strlen(u->scheme). ## Steps to reproduce The following minimal PoC constructs a CURLU handle with host and path, but no explicit scheme, then sets a relative URL using CURLU_DEFAULT_SCHEME: c #include <stdio.h> #include <curl/curl.h> int main(void) { CURLU *u = curl_url(); CURLUcode rc; if(!u) return 2; curl_url_set(u, CURLUPART_HOST, "example.com", 0); curl_url_set(u, CURLUPART_PATH, "/original", 0); rc = curl_url_set(u, CURLUPART_URL, "/newpath", CURLU_DEFAULT_SCHEME); printf("Return code: %d\n", rc); curl_url_cleanup(u); return 0; } Compile and run: bash gcc -o curl-url-default-scheme-poc poc.c -lcurl ./curl-url-default-scheme-poc Expected safe behavior: libcurl should return a CURLUcode error such as CURLUE_MALFORMED_INPUT or otherwise normalize/store the default scheme safely. Observed vulnerable behavior in the original test: process crash / segmentation fault from dereferencing u->scheme in redirect_url(). ## Suggested fix Add a u->scheme validation before using it in redirect_url(), or ensure the default scheme used by urlget_url() is persisted in the CURLU object before redirect_url() is called. Example defensive check: c if(!base || !u || !u->scheme) return CURLUE_MALFORMED_INPUT; const char *protsep = base + strlen(u->scheme) + 3;

Impact

Impact A process using libcurl's URL API can be crashed by reaching this URL parsing path with attacker-controlled or otherwise untrusted relative URL input. The direct security impact is denial of service against applications that: - Build a CURLU handle in stages, setting host/path without an explicit scheme - Accept or process relative URLs - Use CURLU_DEFAULT_SCHEME for convenience or redirect-style normalization If such input is remotely controllable in an application, an attacker may be able to terminate the process by triggering the NULL pointer dereference. I do not claim code execution; this is a crash/availability issue.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original