diff options
author | Ray Satiro <raysatiro@yahoo.com> | 2016-01-26 23:23:15 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2016-01-26 23:42:55 +0100 |
commit | 3017d8a8d8849ebd4feae4f5eae037cd55736a61 (patch) | |
tree | 976231c185eafd16960d905dc73a7ca0c04ff59f /src/tool_cb_hdr.c | |
parent | cea1fd7a9414b628e3b462b08ee3b64f24a689d1 (diff) | |
download | curl-3017d8a8d8849ebd4feae4f5eae037cd55736a61.tar.gz |
curl: avoid local drive traversal when saving file (Windows)
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/DOS is the only OS
where this vulnerability applies.
CVE-2016-0754
Bug: http://curl.haxx.se/docs/adv_20160127B.html
Diffstat (limited to 'src/tool_cb_hdr.c')
-rw-r--r-- | src/tool_cb_hdr.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index fd208e862..0fca39ffa 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -28,6 +28,7 @@ #include "curlx.h" #include "tool_cfgable.h" +#include "tool_doswin.h" #include "tool_msgs.h" #include "tool_cb_hdr.h" @@ -114,18 +115,24 @@ size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) */ len = (ssize_t)cb - (p - str); filename = parse_filename(p, len); - if(filename) { - outs->filename = filename; - outs->alloc_filename = TRUE; - outs->is_cd_filename = TRUE; - outs->s_isreg = TRUE; - outs->fopened = FALSE; - outs->stream = NULL; - hdrcbdata->honor_cd_filename = FALSE; - break; - } - else + if(!filename) + return failure; + +#if defined(MSDOS) || defined(WIN32) + if(sanitize_file_name(&filename)) { + free(filename); return failure; + } +#endif /* MSDOS || WIN32 */ + + outs->filename = filename; + outs->alloc_filename = TRUE; + outs->is_cd_filename = TRUE; + outs->s_isreg = TRUE; + outs->fopened = FALSE; + outs->stream = NULL; + hdrcbdata->honor_cd_filename = FALSE; + break; } } @@ -181,15 +188,12 @@ static char *parse_filename(const char *ptr, size_t len) } /* scan for the end letter and stop there */ - q = p; - while(*q) { - if(q[1] && (q[0] == '\\')) - q++; - else if(q[0] == stop) + for(q = p; *q; ++q) { + if(*q == stop) { + *q = '\0'; break; - q++; + } } - *q = '\0'; /* make sure the file name doesn't end in \r or \n */ q = strchr(p, '\r'); |