curl · Report #4057637
[HIGH] CWE-22 — Path Traversal in FTP Wildcard Download via Unencoded `.` in Escaped Filenames
How it was found
Summary
A malicious or MITM'd FTP server can cause a client using CURLOPT_WILDCARDMATCH to download files outside the intended remote directory, by returning a LIST response with a filename containing .. path-traversal sequences.
Details
In the CURLWC_DOWNLOADING state (lib/ftp.c:4079-4095), each filename returned by the server's LIST response is escaped with curl_easy_escape() before being appended to the current wildcard path:
`char *enc = curl_easy_escape(NULL, finfo->filename, 0);`
...
`tmp_path = curl_maprintf("%s%s", wildcard->path, enc);`
...
`ftp->pathalloc = ftp->path = tmp_path;`
curl_easy_escape() percent-encodes everything except the RFC 3986 unreserved character set (A-Za-z0-9-._~), critically, . is NOT encoded. A filename of ../etc/passwd therefore escapes to ..%2Fetc%2Fpasswd (dots preserved literally, only the / gets encoded).
Immediately afterward, ftp_parse_url_path() (lib/ftp.c:207-227) is called on this same path, and its very first step is:
`result = Curl_urldecode(ftp->path, 0, &ftpc->rawpath, &pathLen, REJECT_CTRL);`
This URL-decodes the path, reconstructing the literal ../etc/passwd sequence. REJECT_CTRL only rejects control characters (confirmed by reading Curl_urldecode's REJECT_CTRL handling), there is no ..-component filtering or path-normalization check anywhere in this flow before the resulting path is used to drive the subsequent CWD/RETR sequence.
PoC
- Attacker controls or MITMs an FTP server.
- The client application uses wildcard matching:
curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L)against a URL likeftp://server/pub/*.txt - The attacker's FTP LIST response includes a filename such as
"../../etc/passwd"(or an absolute-looking component). curl_easy_escape()encodes it to"..%2F..%2Fetc%2Fpasswd"(dots preserved, slashes encoded).- It is concatenated onto the current wildcard path.
ftp_parse_url_path()->Curl_urldecode()decodes it straight back to"../../etc/passwd"(or similar), with only control-character filtering.- The resulting path drives the client's CWD/RETR sequence, traversing outside the directory the calling application intended to browse.
Suggested patch:
After URL-decoding in ftp_parse_url_path(), validate that the resulting
path does not contain ".." components that traverse outside the intended
directory. Alternatively, validate finfo->filename in the
CURLWC_DOWNLOADING state before it is ever escaped reject filenames
containing "/", "..", or an absolute-path leading "/".
Impact
Summary:
An application using CURLOPT_WILDCARDMATCH against an untrusted or compromised FTP server can be made to download files from arbitrary paths on that server, outside the directory the calling code intended, an information-disclosure / path-confinement bypass. Requires the calling application to have opted into wildcard matching; does not affect the default (non-wildcard) FTP/SFTP/HTTP transfer paths.