9 ms·
Xkcd: Heartbleed Explanation
- weavie 13y agoWow. Was it really that simple? The heart beat request sends the text as well as the length it wants back?
- danbruc 13y agoYes. They really only missed the check that the length of the data you sent and the length you said it is are the same.
- sp332 13y agoWell, they also failed to clear memory that includes sensitive data.
- pbhjpbhj 13y agoI'm not a programmer but .. why bother asking you what length it's supposed to be if you're going to strlen() it anyway? Sure you might need to allocate resources if this was carrying a proper payload but here we're just talking about an index. The spec not specifying the max length of the payload seems to be the problem??
- danbruc 13y agoThe maximum length is specified, 65535 bytes, because that is the largest number that fits into the length field. If you have a variable length field you always have to specify the length, otherwise you will never know the actual length and are for example unable to read the next field because you don't know where it starts. There is no real next field in the case of the heart beat packet, only padding, but you still have to figure out the length in order to know what to return. You have the option to specify the length implicitly by using a terminator like a zero byte in a zero delimited string but this is sometimes a bad idea. First you have to scan the entire field just to figure out its length while with an explicitly stored length before the actual data you can just read the length and for example skip to the next field without ever looking at the field. Forgetting to properly terminate the field will of course get you in serious trouble, too. And last but not least using a terminator only works if you have an used symbol (or are willing to perform escaping). In the case of the heartbeat extension there are no restrictions on the content and you can put in arbitrary binary data and therefore something simple like a zero terminator does not work.
- pbhjpbhj 13y agoUsing UDP over IPv4 isn't the max payload size for a packet 65,507 bytes? That would mean that the max length that can be specified is already going to be a potential buffer overflow. What happens if you use specify a zero length? Seems that if the protocol were being defined loosely that should allow for "any length of field that fits within the transport packet" and so allow for larger datagram packets (a la Jumbogram). Is there a trend to leave definitions of these protocols as loose as possible (eg not specifying the response field in the heartbeat as a double/long or whatever) so as to allow hacking it to serve some other use later? Guess I'm going to have to look at the DTLS protocol definitions ...
- danbruc 13y agoTLS is usually used on top of TCP and therefore UDP limits do not apply. I have no idea how implementations on top of UDP or other datagram protocols deal with that issue. For a payload length of zero I would expect to just get back a payload of length zero, but I am be no means a network or even TLS expert and the standard may as well disallow this. And I am to lazy to look it up. It is probably a really bad idea to make your protocol depend on details of an underlying protocol layer. Just imagine sending something over Ethernet and receiving it at the other end over WLAN where both protocols may disagree on the maximum packet size. You usually want your standard as precise as possible without imposing unnecessary and artificial constraints. Being allowed to stuff undefined amounts of data into a heart beat packet just to ease abusing the protocol really seems to call for trouble.
- y0ghur7_xxx 13y agoYes. Here is a PoC in Python: https://gist.github.com/takeshixx/10107280 https://gist.github.com/takeshixx/10107280 On line 42 is the heartbeat request payload. 40 is the length of the message in hex = 64 bytes.
- smtddr 13y agoNo, not "40".... "40 00". https://news.ycombinator.com/item?id=7555156 https://news.ycombinator.com/item?id=7555156 Such that "FF FF" will be 65535 (the 64kb everyone keeps talking about)
- torrent-of-ions 13y agoThe bug is really that simple. The fact that you actually get back sensitive information in a high proportion of requests is due to a few other factors that are a little more difficult to explain. Either way it's a severe potential security breach that is directly attributed to this error.
- masklinn 13y ago> Wow. Was it really that simple? Close enough. > The heart beat request sends the text as well as the length it wants back? The heartbeat sends a payload prefixed by its size. That's perfectly normal design (for variable-size payloads), that way the handler reads the size, allocates a buffer[-1] and uses read(2) to read the payload into the buffer. Otherwise the handler would have to "guess" the payload size, and that never ends well. The problem here is twofold: 1. read(2) may read less than requested, if an attacker gave a bigger size than the actual one for instance. That's why read(2) returns the number of bytes actually read 2. malloc(3) hands out a bunch of memory, without clearing it[0]. Depending on the exact allocator and application runtime, chances are this bit of memory is at least in part freed memory, which is filled with the content of previous allocations such as SSH keys or passwords or whatever (2.) is compounded by OpenSSL having its own freelists on top of malloc which it does not clear, making it certain to hit previously allocated data You're supposed to check the result of read(2) and adjust your payload size and only copy that to the output buffer. Or just error out if the sizes differ. And ideally unless you have very specific reasons not to you'd want to use calloc(3), so that if you forget to check read(2) you return zeroed memory anyway. The first part was forgotten and the second one not done (because "needs fasts!"), the whole input buffer was copied in the output buffer and an attacker gets 64kb[1] worth of previous allocations data. [-1] possibly adding its own constraints on top of that, here the payload's 64KiB so it's not relevant, in other contexts the server could refuse overly large payloads [0] except on BSD with a malloc.conf using the J or Z options [1] because the user-provided length is a 16 bit uint
- weavie 13y agoAn excellent explanation. Thanks.
- gokhan 13y agoHaha. Your comment is so complex it needs another XKCD comic just to make sure all those [-1], (2), 1., [1]'s etc. don't get mixed up.
- StavrosK 13y agoThat's because it was the in-depth, technical explanation of the comic. Based on the GP's comment, the comic is exactly accurate.
- ijk 13y agoPretty much, yes. Here's an analysis of the actual OpenSSL code: http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html http://blog.existentialize.com/diagnosis-of-the-openssl-hear... Here's the patch itself: https://github.com/openssl/openssl/commit/96db9023b881d7cd9f379b0c154650d6c108e9a3#diff-2 https://github.com/openssl/openssl/commit/96db9023b881d7cd9f...
- nyellin 13y agoThis is why xkcd is unique - not because of the puns or nerdy references, but because of Randall's ability to make complicated issues simple.
- alandarev 13y agoBut it was simple in first place. Though a self-explanatory picture describing it is a huge plus to refer for non-IT people.
- nyellin 13y agoSure, it's simple if you realize that memory heaps are sequential and the server's private key can be found after the address of a short-lived packet buffer... It is not trivial explaining all that with simple analogy my grandmother would understand.
- masklinn 13y ago> it's simple if you realize that memory heaps are sequential and the server's private key can be found after the address of a short-lived packet buffer… Your comment seems to imply an out of bounds access (read past the allocated buffer), but heartbleed has no out of bounds access. Instead, it's a problem of malloc (and even more so openssl's freelist scheme) returning non-zeroed memory which can (and often does) hold previously allocated data combined with read(2) not overwriting the whole buffer and not checking read(2)'s return value, which means the aforementioned previously allocated data gets sent back.
- deleted 13y ago[deleted]
- gizmo686 13y agoI had no problem explaining it to my non-technical family members. The way I described it is that the server would return whatever happened to be there.
- 13y ago
- billpg 13y agoI showed this to my wife to see if the cartoon worked with an educated but not-technical person. She subconsciously glossed over the (n LETTERS) part of Meg's requests as just an annotation on the cartoonist's part, not realizing that it was actually part of the request. Once I rephrased the final request as "Server, reply with the 500 letters of HAT", we finally had that light-bulb moment.
- mitosis 13y agoYour wife seems to be affected by the recently discovered vulnerability. It would be advisable to upgrade her firmware to the latest version.
- deleted 13y ago[deleted]
- angelbar 13y agoHN, funny button?
- SimHacker 13y agoAnd don't forget to immediately revoke your old marriage certificate, reissue a new one, and invalidate all your old keys and cookies, or else your relationship is vulnerable to a man in the middle attack, like Dr. Frank-N-Furter did to Brad and Janet! [1] [1] https://www.youtube.com/watch?v=m62xw7EWJDE https://www.youtube.com/watch?v=m62xw7EWJDE
- deleted 13y ago[deleted]
- nsxwolf 13y agoI had the same problem.
- billpg 13y agoYou were showing cartoons to my wife? Sir, I challenge you to fisticuffs at dawn!
- StavrosK 13y agoNice easter egg in the user who wants to change the password to CoHoBaSt (correct-horse-battery-staple).
- AndrewDucker 13y agoCan someone explain why Heartbeat needed to return the text it was sent, rather than always returning an "OK" message? What advantage does returning the text give you?
- jonnydark 13y agoIt verifies that you're actually connected to the server and it is listening to you rather than just some dumb box that keeps nodding and replying with "OK" with glazed over eyes regardless of what you say.
- jon-wood 13y agoSo instead you could be communicating with a marginally less dumb box, which nods and replies with whatever you said instead?
- dferlemann 13y agoIf it can reply whatever you requested accurately, then the established 2-way communication can be said to have the same quality.
- hf 13y agoThat's precisely the point that riles our tinfoil-hated friends: Heartbeat should be a simple matter of hi-ho's ad infinitum (ie: no or constant-space parameters). This is, of course, glossing over the fact that TLS over a TCP link doesn't actually need a heartbeat. TLS/UDP does, granted. Ever heard of DTLS?
- andyjohnson0 13y agoThis has puzzled me too. The RFC that describes the extension [1] seems to be silent on the actual rationale for allowing an arbitrary message. All I can think of is that the designer of the extension wanted to specify a mechanism with enough extensibility to allow requester-generated sequence numbers with arbitrary formats to be sent. Alternatively, if the sender makes the message unpredictable and compares the request and response messages and finds them the same, then this provides some weak "proof" that the responding server is the one that the request was sent to. I don't find either of these particularly convincing though. [1] https://tools.ietf.org/html/rfc6520 https://tools.ietf.org/html/rfc6520
- mixedbit 13y agoSecurity issue explained without Alice, Bob and Malory, this is way too confusing. Who is this Meg character?
- Namrog84 13y agoShe is eve's cousin
- parax 13y ago"And this is, kids, why you always have to validate your input and do not trust on the user".
- nashashmi 13y agoI just began appreciating all the hoops I jump through just to concentrate on things hardly anyone else cares about. It takes me nearly ten times as long to complete a program, and taxes my mind ten times more, and makes me frustrated twice as much about pursuing programming, but after a very sharp practicing curve, makes me hundred times better than the rest of the programmers out there. But, still, I wonder if it's worth it. Especially, considering my boring as hell job.
- oafitupa 13y agowat
- yiedyie 13y agoCheck this answer: http://security.stackexchange.com/a/55539/15901 http://security.stackexchange.com/a/55539/15901
- spbhat1989 13y agoXkcd is best at simplifying the most complex things and complicating the most simple things! :)
- danyork 13y agoBrilliantly done! Great to have this out there to help explain the issue to non-developers.
- damon_c 13y agoIt's hard to believe that even with all of our slavish mantra repetition about not trusting user submitted data... the freaking web server trusts user submitted data. We're all going to have to start reading more source code...