-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Commit
A missing bounds check in the handling of the TLS heartbeat extension can be used to reveal up to 64k of memory to a connected client or server. Thanks for Neel Mehta of Google Security for discovering this bug and to Adam Langley <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> for preparing the fix (CVE-2014-0160) (cherry picked from commit 96db902)
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1330,26 +1330,36 @@ dtls1_process_heartbeat(SSL *s) | |
unsigned int payload; | ||
unsigned int padding = 16; /* Use minimum padding */ | ||
|
||
/* Read type and payload length first */ | ||
hbtype = *p++; | ||
n2s(p, payload); | ||
pl = p; | ||
|
||
if (s->msg_callback) | ||
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, | ||
&s->s3->rrec.data[0], s->s3->rrec.length, | ||
s, s->msg_callback_arg); | ||
|
||
/* Read type and payload length first */ | ||
This comment has been minimized.
Sorry, something went wrong. |
||
if (1 + 2 + 16 > s->s3->rrec.length) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
rtepowers
|
||
return 0; /* silently discard */ | ||
hbtype = *p++; | ||
n2s(p, payload); | ||
if (1 + 2 + payload + 16 > s->s3->rrec.length) | ||
This comment has been minimized.
Sorry, something went wrong. |
||
return 0; /* silently discard per RFC 6520 sec. 4 */ | ||
pl = p; | ||
|
||
if (hbtype == TLS1_HB_REQUEST) | ||
{ | ||
unsigned char *buffer, *bp; | ||
unsigned int write_length = 1 /* heartbeat type */ + | ||
2 /* heartbeat length */ + | ||
payload + padding; | ||
This comment has been minimized.
Sorry, something went wrong.
mozjag
|
||
int r; | ||
|
||
if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) | ||
return 0; | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
/* Allocate memory for the response, size is 1 byte | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
* message type, plus 2 bytes payload length, plus | ||
* payload, plus padding | ||
*/ | ||
buffer = OPENSSL_malloc(1 + 2 + payload + padding); | ||
buffer = OPENSSL_malloc(write_length); | ||
bp = buffer; | ||
|
||
/* Enter response type, length and copy payload */ | ||
|
@@ -1360,11 +1370,11 @@ dtls1_process_heartbeat(SSL *s) | |
/* Random padding */ | ||
RAND_pseudo_bytes(bp, padding); | ||
|
||
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); | ||
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); | ||
|
||
if (r >= 0 && s->msg_callback) | ||
s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, | ||
buffer, 3 + payload + padding, | ||
buffer, write_length, | ||
s, s->msg_callback_arg); | ||
|
||
OPENSSL_free(buffer); | ||
|
25 comments
on commit 731f431
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I notice that the recommendation on http://heartbleed.com to disable support for the heartbeat extension has not been followed.
"Should heartbeat be removed to aid in detection of vulnerable services?
Recovery from this bug could benefit if the new version of the OpenSSL would both fix the bug and disable heartbeat temporarily until some future version. It appears that majority if not almost all TLS implementations that respond to the heartbeat request today are vulnerable versions of OpenSSL. If only vulnerable versions of OpenSSL would continue to respond to the heartbeat for next few months then large scale coordinated response to reach owners of vulnerable services would become more feasible."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is simple to tell the difference between a TLS implementation that handles heartbeat requests correctly, and an implementation that is vulnerable to Heartbleed.
To do so, replace s2n(payload, p); on line 4086 with s2n(LARGE_NUMBER, p);. Replace the "silently discard" logic with any desired logging. Then compile and send heartbeat requests with:
./openssl s_client -connect www.serverundertest.com:443
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be shared!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are the braces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They did it in hustle so no time to put braces!!11
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lwneal, I've been using the simple python tester published here: https://github.com/musalbas/heartbleed-masstest
It's been one full day and I've found a handful of sites in my web history that are still vulnerable...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you douglasheld for giving hackers a tool to find all the exposed sites on the Internet.
Perhaps if the code were a bit more readable in not in the format, 1 + 2 + payload + 16, this bug would have been caught earlier. It's ok though, it's not like the world's data security relies on this or anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we imagine that writing tests could help make sure regressions are not introduced? Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jlmalone perhaps if you were making more pull requests instead of snarky comments, the code would be more readable. It's OK though, it's not like you're the only one to whine about FOSS while benefiting from it without contributing anything in return.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we imagine that writing tests could help make sure regressions are not introduced? Thanks.
Writing tests is for those mediocre developers who spend their lives writing Java (ugh). Its much better to just have a handful of printf-esque statements in the code (commented out, of course).
Also, defining constants, especially those with human-readable names, is a massive affront to performance! If another developer wants to know that "payload" actually describes the size of the buffer, they should go read the RFC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mkotelba if named constants are such a performance hit, maybe the code could be transpiled with constants replaced before compiling, so source is easier to understand, and performance is not hit.
It's late, I am going to go read some RFC specs to put myself to sleep.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, you know, #define.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writing tests is for those mediocre developers who spend their lives writing Java (ugh). Its much better to just have a handful of printf-esque statements in the code (commented out, of course).
@mkotelba You don't write test, so your users do the testing for you, they find a stupid bug and they ask : who wrote the stupid code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mkotelba I cannot find any important softwares which don't need testing. If you managed to do that, please let me know. So that I can learn from you about how to write correct and efficient code in such a brand new way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read a sarcastic tone in @mkotelba's post. If it wasn't intended to be sarcastic, then this thread is becoming even more hilarious!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it only me or does anyone else agree that such a high profile lib could benefit for a robust test suite?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brupm, I agree wholeheartedly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a functional/unit test would be really helpful, except that those typically don't identify security vulnerabilities (because they are not designed to).
Think about it however: some simple unit tests would have found the Apple "goto fail" -- which was in the wild for what, years? Pretty damning.
As for security assurance of infrastructure critical code, the path has to be:
- declutter the code. Nobody can read OpenSSL, this has been documented.
- Periodic security architecture reviews.
- My own field is static analysis. The available static analysis tools should be coming up clean for the core library, plus sample code and reference implementations.
These steps are not impossible to achieve, but the list has correctly identified that the "many eyes" are not bringing this about automatically. "Many eyes" are really good for catching a broken build, but not design flaws such as this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Higher level language" was my first reaction to this bug. But which one? There's a catch-22 here: the more universal the HLL the more clutter is likely to result in implementing any given algorithm. But the more targeted an HLL is to any domain, the more compilers you need, one for each HLL, each with its own opportunities for bugs in the compiler.
For lowering the incidence of heartbleed-type bugs, library coordination between servers might be a more effective and more immediately implementable solution than higher level languages. Why is it so hard to provide sendstring and receivestring functions that are provably unspoofable? That's not a rhetorical question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@corsair It was so obvious that no one needed to write about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you read the thread? It wasn't obvious to the people who responded seriously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, I'm glad I forgot that I posted in this thread for a week.
Yes, of course I was being sarcastic :) I tend to work in the land of Java most of the time, and often on projects that are heavily security-focused (fancy S/MIME processing, etc).
Call me a fanboy if you must, but even the most complicated, massive, and poorly-documented Java libs/APIs out there (relevant ex., BounceyCastle) still manage to have a ~passable amount of test coverage. The fact that throwing a single JUnit or TestNG dependency into your project makes even complex testing a breeze certainly helps.
In regards to OpenSSL, @douglasheld is dead-on in his ideas: hell, even just deciding on a given code-style configuration and then letting a code formatter apply it to the entire codebase would help tremendously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hamradiojava Haha that's a good one~~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've posted #81 to add a unit test to prevent regression of the Heartbleed bug.
The following block of code is way too large to be repeated in both
d1_both.c
andtl_lib.c
. I'm sure there are many other common blocks of code between these files (and the project at large given its reputation) as well.