CVE-2014-3707
duphandle read out of bounds
Project curl Security Advisory, November 5th 2014 - Permalink
VULNERABILITY
libcurl's function curl_easy_duphandle()
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 are 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:
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. Thestrdup()
function of course allocates memory off the heap.After duplication of the handle data, the pointer used to read from when sending the data was not updated. 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 copies 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 cannot 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.
CWE-126: Buffer Over-read
Severity: Medium
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.17.1 and libcurl >= 7.39.0
- Introduced-in: https://github.com/curl/curl/commit/a005243908803662d4a0542
libcurl is used by many applications, but not always advertised as such!
SOLUTION
libcurl 7.39.0 makes sure that the buffer area is duplicated and presumed to be binary.
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".
TIMELINE
It was first reported to the curl project on September 16th 2014.
We contacted distros@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
- Help-by: Stas Malyshev, Dan Fandrich, Tomas Hoger
- Patched-by: Daniel Stenberg
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.
Thanks a lot!