mirror of
https://github.com/curl/curl.git
synced 2024-11-21 01:16:58 +08:00
- David Kierznowski notified us about a security flaw
(http://curl.haxx.se/docs/adv_20090303.html also known as CVE-2009-0037) in which previous libcurl versions (by design) can be tricked to access an arbitrary local/different file instead of a remote one when CURLOPT_FOLLOWLOCATION is enabled. This flaw is now fixed in this release together this the addition of two new setopt options for controlling this new behavior: o CURLOPT_REDIR_PROTOCOLS controls what protocols libcurl is allowed to follow to when CURLOPT_FOLLOWLOCATION is enabled. By default, this option excludes the FILE and SCP protocols and thus you nee to explicitly allow them in your app if you really want that behavior. o CURLOPT_PROTOCOLS controls what protocol(s) libcurl is allowed to fetch using the primary URL option. This is useful if you want to allow a user or other outsiders control what URL to pass to libcurl and yet not allow all protocols libcurl may have been built to support.
This commit is contained in:
parent
90b804d3fa
commit
042cc1f69e
21
CHANGES
21
CHANGES
@ -6,6 +6,27 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Version 7.19.4 (3 March 2009)
|
||||
|
||||
Daniel Stenberg (3 Mar 2009)
|
||||
- David Kierznowski notified us about a security flaw
|
||||
(http://curl.haxx.se/docs/adv_20090303.html also known as CVE-2009-0037) in
|
||||
which previous libcurl versions (by design) can be tricked to access an
|
||||
arbitrary local/different file instead of a remote one when
|
||||
CURLOPT_FOLLOWLOCATION is enabled. This flaw is now fixed in this release
|
||||
together this the addition of two new setopt options for controlling this
|
||||
new behavior:
|
||||
|
||||
o CURLOPT_REDIR_PROTOCOLS controls what protocols libcurl is allowed to
|
||||
follow to when CURLOPT_FOLLOWLOCATION is enabled. By default, this option
|
||||
excludes the FILE and SCP protocols and thus you nee to explicitly allow
|
||||
them in your app if you really want that behavior.
|
||||
|
||||
o CURLOPT_PROTOCOLS controls what protocol(s) libcurl is allowed to fetch
|
||||
using the primary URL option. This is useful if you want to allow a user or
|
||||
other outsiders control what URL to pass to libcurl and yet not allow all
|
||||
protocols libcurl may have been built to support.
|
||||
|
||||
Daniel Stenberg (27 Feb 2009)
|
||||
- Senthil Raja Velu reported a problem when CURLOPT_INTERFACE and
|
||||
CURLOPT_LOCALPORT were used together (the local port bind failed), and
|
||||
|
@ -2,11 +2,16 @@ Curl and libcurl 7.19.4
|
||||
|
||||
Public curl releases: 110
|
||||
Command line options: 132
|
||||
curl_easy_setopt() options: 161
|
||||
curl_easy_setopt() options: 163
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 38
|
||||
Contributors: 700
|
||||
|
||||
This release includes the following security-related fix:
|
||||
|
||||
o CVE-2009-0037 with the curl advisory here:
|
||||
http://curl.haxx.se/docs/adv_20090303.html
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added CURLOPT_NOPROXY and the corresponding --noproxy
|
||||
@ -24,6 +29,7 @@ This release includes the following changes:
|
||||
o CURLOPT_FTP_CREATE_MISSING_DIRS can now be set to 2 to retry the CWD even
|
||||
when MKD fails
|
||||
o GnuTLS initing moved to curl_global_init()
|
||||
o Added CURLOPT_REDIR_PROTOCOLS and CURLOPT_PROTOCOLS
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
@ -59,6 +65,6 @@ advice from friends like these:
|
||||
Patrick Scott, Hidemoto Nakada, Jocelyn Jaubert, Andre Guibert de Bruet,
|
||||
Kamil Dudka, Patrik Thunstrom, Linus Nielsen Feltzing, Mark Incley,
|
||||
Daniel Johnson, James Cheng, Brian J. Murrell, Senthil Raja Velu,
|
||||
Markus Koetter
|
||||
Markus Koetter, David Kierznowski, Michal Marek
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@ -440,6 +440,26 @@ The string given to CURLOPT_URL must be url-encoded and follow RFC 2396
|
||||
|
||||
\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
|
||||
\fIcurl_easy_perform(3)\fP is called.
|
||||
|
||||
\fICURLOPT_PROTOCOLS\fP can be used to limit what protocols libcurl will use
|
||||
for this transfer, independent of what libcurl has been compiled to
|
||||
support. That may be useful if you accept the URL from an external source and
|
||||
want to limit the accessibility.
|
||||
.IP CURLOPT_PROTOCOLS
|
||||
Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
|
||||
limits what protocols libcurl may use in the transfer. This allows you to have
|
||||
a libcurl built to support a wide range of protocols but still limit specific
|
||||
transfers to only be allowed to use a subset of them. By default libcurl will
|
||||
accept all protocols it supports. See also
|
||||
\fICURLOPT_REDIR_PROTOCOLS\fP. (Added in 7.19.4)
|
||||
.IP CURLOPT_REDIR_PROTOCOLS
|
||||
Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
|
||||
limits what protocols libcurl may use in a transfer that it follows to in a
|
||||
redirect when \fICURLOPT_FOLLOWLOCATION\fP is enabled. This allows you to
|
||||
limit specific transfers to only be allowed to use a subset of protocols in
|
||||
redirections. By default libcurl will allow all protocols except for FILE and
|
||||
SCP. This is a difference compared to pre-7.19.4 versions which
|
||||
unconditionally would follow to all protocols supported. (Added in 7.19.4)
|
||||
.IP CURLOPT_PROXY
|
||||
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
|
||||
string holding the host name or dotted IP address. To specify port number in
|
||||
@ -743,6 +763,10 @@ This means that the library will re-send the same request on the new location
|
||||
and follow new Location: headers all the way until no more such headers are
|
||||
returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects
|
||||
libcurl will follow.
|
||||
|
||||
NOTE: since 7.19.4, libcurl can limit to what protocols it will automatically
|
||||
follow. The accepted protocols are set with \fICURLOPT_REDIR_PROTOCOLS\fP and
|
||||
it excludes the FILE protocol by default.
|
||||
.IP CURLOPT_UNRESTRICTED_AUTH
|
||||
A parameter set to 1 tells the library it can continue to send authentication
|
||||
(user+password) when following locations, even when hostname changed. This
|
||||
|
@ -191,6 +191,7 @@ CURLOPT_PRIVATE 7.10.3
|
||||
CURLOPT_PROGRESSDATA 7.1
|
||||
CURLOPT_PROGRESSFUNCTION 7.1
|
||||
CURLOPT_PROGRESSMODE 7.1 - 7.9.2
|
||||
CURLOPT_PROTOCOLS 7.19.4
|
||||
CURLOPT_PROXY 7.1
|
||||
CURLOPT_PROXYAUTH 7.10.7
|
||||
CURLOPT_PROXYPASSWORD 7.19.1
|
||||
@ -205,6 +206,7 @@ CURLOPT_RANDOM_FILE 7.7
|
||||
CURLOPT_RANGE 7.1
|
||||
CURLOPT_READDATA 7.9.7
|
||||
CURLOPT_READFUNCTION 7.1
|
||||
CURLOPT_REDIR_PROTOCOLS 7.19.4
|
||||
CURLOPT_REFERER 7.1
|
||||
CURLOPT_RESUME_FROM 7.1
|
||||
CURLOPT_RESUME_FROM_LARGE 7.11.0
|
||||
@ -261,6 +263,19 @@ CURLOPT_VERBOSE 7.1
|
||||
CURLOPT_WRITEDATA 7.9.7
|
||||
CURLOPT_WRITEFUNCTION 7.1
|
||||
CURLOPT_WRITEHEADER 7.1
|
||||
CURLPROTO_ALL 7.19.4
|
||||
CURLPROTO_DICT 7.19.4
|
||||
CURLPROTO_FILE 7.19.4
|
||||
CURLPROTO_FTP 7.19.4
|
||||
CURLPROTO_FTPS 7.19.4
|
||||
CURLPROTO_HTTP 7.19.4
|
||||
CURLPROTO_HTTPS 7.19.4
|
||||
CURLPROTO_LDAP 7.19.4
|
||||
CURLPROTO_LDAPS 7.19.4
|
||||
CURLPROTO_SCP 7.19.4
|
||||
CURLPROTO_SFTP 7.19.4
|
||||
CURLPROTO_TELNET 7.19.4
|
||||
CURLPROTO_TFTP 7.19.4
|
||||
CURLPROXY_HTTP 7.10
|
||||
CURLPROXY_HTTP_1_0 7.19.4
|
||||
CURLPROXY_SOCKS4 7.10
|
||||
|
@ -550,6 +550,21 @@ typedef enum {
|
||||
CURLFTPMETHOD_LAST /* not an option, never use */
|
||||
} curl_ftpmethod;
|
||||
|
||||
/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
|
||||
#define CURLPROTO_HTTP (1<<0)
|
||||
#define CURLPROTO_HTTPS (1<<1)
|
||||
#define CURLPROTO_FTP (1<<2)
|
||||
#define CURLPROTO_FTPS (1<<3)
|
||||
#define CURLPROTO_SCP (1<<4)
|
||||
#define CURLPROTO_SFTP (1<<5)
|
||||
#define CURLPROTO_TELNET (1<<6)
|
||||
#define CURLPROTO_LDAP (1<<7)
|
||||
#define CURLPROTO_LDAPS (1<<8)
|
||||
#define CURLPROTO_DICT (1<<9)
|
||||
#define CURLPROTO_FILE (1<<10)
|
||||
#define CURLPROTO_TFTP (1<<11)
|
||||
#define CURLPROTO_ALL (~0) /* enable everything */
|
||||
|
||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||
but 32 */
|
||||
#define CURLOPTTYPE_LONG 0
|
||||
@ -1185,6 +1200,18 @@ typedef enum {
|
||||
/* Socks Service */
|
||||
CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
|
||||
|
||||
/* set the bitmask for the protocols that are allowed to be used for the
|
||||
transfer, which thus helps the app which takes URLs from users or other
|
||||
external inputs and want to restrict what protocol(s) to deal
|
||||
with. Defaults to CURLPROTO_ALL. */
|
||||
CINIT(PROTOCOLS, LONG, 181),
|
||||
|
||||
/* set the bitmask for the protocols that libcurl is allowed to follow to,
|
||||
as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
|
||||
to be set in both bitmasks to be allowed to get redirected to. Defaults
|
||||
to all protocols except FILE and SCP. */
|
||||
CINIT(REDIR_PROTOCOLS, LONG, 182),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
36
lib/url.c
36
lib/url.c
@ -683,6 +683,12 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
||||
set->new_file_perms = 0644; /* Default permissions */
|
||||
set->new_directory_perms = 0755; /* Default permissions */
|
||||
|
||||
/* for the *protocols fields we don't use the CURLPROTO_ALL convenience
|
||||
define since we internally only use the lower 16 bits for the passed
|
||||
in bitmask to not conflict with the private bits */
|
||||
set->allowed_protocols = PROT_EXTMASK;
|
||||
set->redir_protocols =
|
||||
PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
/*
|
||||
@ -2217,6 +2223,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->set.scope = (unsigned int) va_arg(param, long);
|
||||
break;
|
||||
|
||||
case CURLOPT_PROTOCOLS:
|
||||
/* set the bitmask for the protocols that are allowed to be used for the
|
||||
transfer, which thus helps the app which takes URLs from users or other
|
||||
external inputs and want to restrict what protocol(s) to deal
|
||||
with. Defaults to CURLPROTO_ALL. */
|
||||
data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
|
||||
break;
|
||||
|
||||
case CURLOPT_REDIR_PROTOCOLS:
|
||||
/* set the bitmask for the protocols that libcurl is allowed to follow to,
|
||||
as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
|
||||
to be set in both bitmasks to be allowed to get redirected to. Defaults
|
||||
to all protocols except FILE and SCP. */
|
||||
data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unknown tag and its companion, just ignore: */
|
||||
result = CURLE_FAILED_INIT; /* correct this */
|
||||
@ -3371,7 +3393,19 @@ static CURLcode setup_connection_internals(struct SessionHandle *data,
|
||||
|
||||
for (pp = protocols; (p = *pp) != NULL; pp++)
|
||||
if(Curl_raw_equal(p->scheme, conn->protostr)) {
|
||||
/* Protocol found in table. Perform setup complement if some. */
|
||||
/* Protocol found in table. Check if allowed */
|
||||
if(!(data->set.allowed_protocols & p->protocol))
|
||||
/* nope, get out */
|
||||
break;
|
||||
|
||||
/* it is allowed for "normal" request, now do an extra check if this is
|
||||
the result of a redirect */
|
||||
if(data->state.this_is_a_follow &&
|
||||
!(data->set.redir_protocols & p->protocol))
|
||||
/* nope, get out */
|
||||
break;
|
||||
|
||||
/* Perform setup complement if some. */
|
||||
conn->handler = p;
|
||||
|
||||
if(p->setup_connection) {
|
||||
|
@ -891,19 +891,26 @@ struct connectdata {
|
||||
long connectindex; /* what index in the connection cache connects index this
|
||||
particular struct has */
|
||||
long protocol; /* PROT_* flags concerning the protocol set */
|
||||
#define PROT_MISSING (1<<0)
|
||||
#define PROT_HTTP (1<<2)
|
||||
#define PROT_HTTPS (1<<3)
|
||||
#define PROT_FTP (1<<4)
|
||||
#define PROT_TELNET (1<<5)
|
||||
#define PROT_DICT (1<<6)
|
||||
#define PROT_LDAP (1<<7)
|
||||
#define PROT_FILE (1<<8)
|
||||
#define PROT_FTPS (1<<9)
|
||||
#define PROT_SSL (1<<10) /* protocol requires SSL */
|
||||
#define PROT_TFTP (1<<11)
|
||||
#define PROT_SCP (1<<12)
|
||||
#define PROT_SFTP (1<<13)
|
||||
#define PROT_HTTP CURLPROTO_HTTP
|
||||
#define PROT_HTTPS CURLPROTO_HTTPS
|
||||
#define PROT_FTP CURLPROTO_FTP
|
||||
#define PROT_TELNET CURLPROTO_TELNET
|
||||
#define PROT_DICT CURLPROTO_DICT
|
||||
#define PROT_LDAP CURLPROTO_LDAP
|
||||
#define PROT_FILE CURLPROTO_FILE
|
||||
#define PROT_FTPS CURLPROTO_FTPS
|
||||
#define PROT_TFTP CURLPROTO_TFTP
|
||||
#define PROT_SCP CURLPROTO_SCP
|
||||
#define PROT_SFTP CURLPROTO_SFTP
|
||||
|
||||
/* CURLPROTO_TFTP (1<<11) is currently the highest used bit in the public
|
||||
bitmask. We make sure we use "private bits" above the first 16 to make
|
||||
things easier. */
|
||||
|
||||
#define PROT_EXTMASK 0xffff
|
||||
|
||||
#define PROT_SSL (1<<22) /* protocol requires SSL */
|
||||
#define PROT_MISSING (1<<23)
|
||||
|
||||
#define PROT_CLOSEACTION PROT_FTP /* these ones need action before socket
|
||||
close */
|
||||
@ -1533,6 +1540,8 @@ struct UserDefined {
|
||||
via an HTTP proxy */
|
||||
char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
|
||||
unsigned int scope; /* address scope for IPv6 */
|
||||
long allowed_protocols;
|
||||
long redir_protocols;
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
long socks5_gssapi_nec; /* flag to support nec socks5 server */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user