cURL / Mailing Lists / curl-users / Single Mail

curl-users

[SECURITY ADVISORY] libcurl duphandle read out of bounds

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Wed, 5 Nov 2014 08:58:49 +0100 (CET)

libcurl duphandle read out of bounds
====================================

Project cURL Security Advisory, November 5th 2014 -
[Permalink](http://curl.haxx.se/docs/adv_20141105.html)

VULNERABILITY
-------------

libcurl's function
[`curl_easy_duphandle()`](http://curl.haxx.se/libcurl/c/curl_easy_duphandle.html)
has a bug that can lead to libcurl eventually sending off sensitive data that
was not intended for sending.

When doing an HTTP POST transfer with libcurl, you can use the
`CURLOPT_COPYPOSTFIELDS` option to specify a memory area holding the data to
send to the remote server. The memory area's size is set with a separate
option, for example `CURLOPT_POSTFIELDSIZE`.

As the name implies, the data in the specified buffer is copied to a privately
held memory buffer that libcurl allocates on the heap. The memory area is
associated with the common CURL handle, often referred to as an "easy handle".

This handle can be duplicated by an application to create an identical copy,
and all the already set options and data is then also similarly cloned and
will be associated with the newly returned handle. This also includes the data
to send in an HTTP POST request.

The internal libcurl function that duplicates options from the old handle to
the new had two problems:

1. It mistakenly treated the post data buffer as if it was a C string which is
    assumed to end with a zero byte. strdup() was subsequently used to
    duplicate the post data buffer, and as a post data buffer can both
    legitimately contain a zero byte, or may not contain any zero bytes at all
    (including a tailing one), strdup() could create a copy that a) was too
    small b) was too large or c) could crash due to reading an inaccessible
    memory area. The strdup() function of course allocates memory off the heap.

2. After duplication of the handle data, the pointer used to read from when
    sending the data was not updated. So when sending off the post, libcurl
    would still read from the original handle's buffer which at that time could
    have been freed or reused for other purposes.

When libcurl subsequently constructs the HTTP POST request and includes data
for the protocol body it will memcpy() data from that pointer using the old
size and the old pointer. This makes a read from the wrong place and can lead
to libcurl inserting data into the request that happens to be stored at that
places in memory at that time.

We are not aware of anyone having been able to actually exploit this for
nefarious purposes, but we can't exclude that it is possible or even might
already have been exploited.

INFO

----
This bug requires `CURLOPT_COPYPOSTFIELDS` and `curl_easy_duphandle()` to be
used in that order, and then the duplicate handle must be used to perform the
HTTP POST.
The curl tool is not affected, it does not use this sequence.
The Common Vulnerabilities and Exposures (CVE) project has assigned the name
CVE-2014-3707 to this issue.
AFFECTED VERSIONS
-----------------
This bug has existed since `CURLOPT_COPYPOSTFIELDS` was introduced.
- Affected versions: from libcurl 7.17.1 to and including 7.38.0
- Not affected versions: libcurl >= 7.39.0
libcurl is used by many applications, but not always advertised as such!
THE SOLUTION
------------
libcurl 7.39.0 makes sure that the buffer area is duplicated and presumed to
be binary.
A patch for this problem is available at:
     http://curl.haxx.se/CVE-2014-3707.patch
RECOMMENDATIONS
---------------
We suggest you take one of the following actions immediately, in order of
preference:
A - Upgrade to curl and libcurl 7.39.0
B - Apply the patch and rebuild libcurl
C - Avoid using `CURLOPT_COPYPOSTFIELDS` then `curl_easy_duphandle()`
If you are using PHP/CURL, we advice you to avoid `curl_copy_handle()` after
`CURLOPT_POSTFIELDS`, since PHP then uses `CURLOPT_COPYPOSTFIELDS` "under the
hood".
TIME LINE
---------
It was first reported to the curl project on September 16th 2014.
We contacted distros_at_openwall on October 20.
libcurl 7.39.0 was released on November 5th 2014, coordinated with the
publication of this advisory.
CREDITS
-------
Reported by Symeon Paraschoudis. Stas Malyshev helped us understand and repeat
the problem. Dan Fandrich helped assess the security risk. Tomas Hoger
analyzed the second part of the bug. Patch written by Daniel Stenberg.
Thanks a lot!
-- 
  / 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.html
Received on 2014-11-05