curl · Report #3923212
URL API: triple-slash parses path segment as hostname
How it was found
Summary
libcurl's URL API misparses http:///host/path. Per RFC 3986, the authority between // and / is empty, so /host/path is the path. But parseurl() in lib/urlapi.c treats the first segment as the hostname. On line ~1087, the slash counter i reaches 3, which is within the valid 1-3 range, and hostp is set to whatever follows the third slash. The file:// scheme has special handling that correctly handles empty authority — this fix should be generalized to other schemes.
Affected version
libcurl 8.5.0 (Ubuntu 24.04) and 8.21.0 (latest). Confirmed on both. curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13
Steps To Reproduce
- Compile and run the attached poc_tripleslash.c
- Observe: http:///169.254.169.254/latest/meta-data/ → host="169.254.169.254", path="/latest/meta-data/" Expected: host="" (empty authority), path="/169.254.169.254/latest/meta-data/"
- Also confirmed via curl CLI:
curl -w "%{url_effective}" http:///pathOutputs: http://path/ (path became hostname)
Impact
An application that constructs URLs from user input and validates the parsed hostname via curl_url_get(CURLUPART_HOST) can be tricked into making requests to attacker-chosen hosts. For example, if user input "/169.254.169.254/latest/meta-data/" is appended to "http://", curl parses host="169.254.169.254", enabling SSRF to cloud metadata endpoints.