curl-users
[SECURITY ADVISORY] remote file name path traversal in curl tool for Windows
Date: Wed, 27 Jan 2016 08:46:09 +0100 (CET)
remote file name path traversal in curl tool for Windows
========================================================
Project cURL Security Advisory, January 27th 2016 -
[Permalink](http://curl.haxx.se/docs/adv_20160127B.html)
VULNERABILITY
-------------
curl does not sanitize colons in a remote file name that is used as the local
file name. This may lead to a vulnerability on systems where the colon is a
special path character. Currently Windows is the only OS where this
vulnerability applies.
curl offers command line options --remote-name (also usable as -O) and
--remote-header-name (also usable as -J). When both of those options are used
together (-OJ) and the server provides a remote file name for the content,
curl will write its output to that server-provided file name, as long as that
file does not already exist. If it does exist curl will fail to write.
If both options are used together (-OJ) but the server does not provide a
remote file name, or if -O is used without -J, curl will write output to a
file name based solely on the remote file name in the URL string provided by
the user, regardless of whether or not that file already exists.
In either case curl does not sanitize colons in the file name. As a result in
Windows it is possible and unintended behavior for curl to write to a file in
the working directory of a drive that is not the current drive (ie outside the
current working directory), and also possible to write to a file's alternate
data stream.
For example if curl -OJ and the server sends filename=f:foo curl will
incorrectly write foo to the working directory for drive F even if drive F
isn't the current drive. For a more detailed explanation see the 'MORE
BACKGROUND AND EXAMPLE' section at the end of this notice.
Though no known exploit is available for this issue, writing one would be
undemanding and could be serious depending on the name of the file and where
it ends up being written.
INFO
---- This flaw only affects the curl command line tool as this is a feature not present or provided by libcurl. The Common Vulnerabilities and Exposures (CVE) project has assigned the name CVE-2016-0754 to this issue. AFFECTED VERSIONS ----------------- In the case of using a remote file name provided by the user (-O without -J), the feature has existed since inception. <- check this I'm not sure. - Affected versions (-O): curl <= 7.46.0 - Not affected versions (-O): curl >= 7.47.0 In the case of using a remote file name provided by the server (-OJ), the feature was added in 7.20.0 and didn't exist before then. - Affected versions (-OJ): curl 7.20.0 to and including 7.46.0 - Not affected versions (-OJ): curl < 7.20.0 and curl >= 7.47.0 THE SOLUTION ------------ Starting in curl 7.47.0 the curl tool in Windows will replace all colons in a remote file name with underscores. For example if f:foo::$DATA is the remote file name it will be sanitized as f_foo__$DATA . A patch is available at: http://curl.haxx.se/CVE-2016-0754.patch Exercise judicious use of the -J option. The -J option when combined with -O lets the server choose the file name. Do you trust the server you are using the -J option on? Is your connection to the server vulnerable to a man-in-the-middle attack? Have you enabled location redirects and the server may send you somewhere untrustworthy? In any of these cases, even with this vulnerability fixed know that if you use the -J option it will still be possible for a rogue server to send you the name of a DLL or other file that could possibly be loaded automatically by Windows or some third party software. RECOMMENDATIONS --------------- We suggest you take one of the following actions immediately, in order of preference: A - Upgrade curl and libcurl to version 7.47.0. B - Apply the patch to your version and rebuild. C - If you cannot do (A) or (B) it is suggested you do not use -J on Windows. If you choose to continue to use -O without -J it is your responsibility to check that the URL you pass does not have a remote file name that could be exploited. Regardless of which action you take, exercise judicious use of the -J option as described in THE SOLUTION. TIME LINE --------- It was first reported to the curl project on November 30 2015. We contacted distros_at_openwall on January 21 2016. curl 7.47.0 was released on January 27 2016, coordinated with the publication of this advisory. CREDITS ------- Reported and patched by Ray Satiro (Jay). Thanks a lot! MORE BACKGROUND AND EXAMPLE --------------------------- In Windows if a colon is used to specify a drive letter for a path and there is a slash or backslash (hereafter path separator) that proceeds the colon it means start from the root of the drive, but if that slash is omitted it means start from the current working directory of the drive. - C:\foo => Windows looks for foo in the root directory of drive C. - C:foo => Windows looks for foo in the working directory of drive C. --- A process in Windows on its creation may inherit a list of drives and their working directories from its parent, and one of those is the current working directory. For example a command prompt is open and has these working directories: - Drive C, Path \bar\baz\ - Drive D, Path \ - Drive E, Path \qux\ <-- Current - Drive F, Path \ Assume other drives were not accessed which means they default to their root. A user running curl from that command prompt would expect that their file will be output to the current working directory, E:\qux\ in this example. However that may not happen if there is a colon in the filename. curl has a function which will strip the path to get the file name by removing the last path separator and everything that precedes it. In the case of a colon without a path separator that comes after it, it is not removed from the file name. Following this example: In the case of -O without -J recall that the filename is parsed from the user- supplied URL, and is written regardless of whether the file already exists. `curl -O http://somewhere/f:foo` => curl writes output to f:\foo `curl -O http://somewhere/c:foo` => curl writes output to c:\bar\baz\foo In the case of -O with -J recall that the file name is parsed from the server's "Content-Disposition:" header if one is given (eg `Content-Disposition: attachment; filename=abc`) and in that case the file is written only if it does not already exist. `curl -OJ http://somewhere/somefile` => Server sends filename=f:foo curl writes output to f:\foo `curl -OJ http://somewhere/somefile` => Server sends filename=c:foo curl writes output to c:\bar\baz\foo -- / daniel.haxx.se ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-users FAQ: http://curl.haxx.se/docs/faq.html Etiquette: http://curl.haxx.se/mail/etiquette.htmlReceived on 2016-01-27