liveBook · Manning

Heartbeat extension

As explained in Hacking Cryptography

The TLS heartbeat extension is a protocol extension that lets a peer request an arbitrary payload to be echoed for connection liveness checking.

The TLS heartbeat extension checks connection liveness by letting a client request an arbitrary payload back from the server. A normal request might ask for the 12-byte payload “good_morning”; the client verifies that the response matches. section 10.6

The security failure appears when the requested payload length is trusted without checking the bytes actually supplied. A malicious client can request thousands of bytes while sending only a few, causing the server to read beyond the heartbeat buffer and disclose adjacent memory. section 10.6

Figure 10.9 The Heartbleed vulnerability: a malicious client requests a very long heartbeat but provides very little data to echo. The vulnerable server reads beyond the heartbeat buffer into other areas of memory.
figure

Trace how a long heartbeat request with little payload makes a vulnerable server return unintended memory. section 10.6

Listing 10.7 (OpenSSL 1.0.1f)—ssl/d1_both.c
#ifndef OPENSSL_NO_HEARTBEATS
int
dtls1_process_heartbeat(SSL *s)
  {
  unsigned char *p = &s->s3->rrec.data[0], *pl;  #1
  unsigned short hbtype;
  unsigned int payload;
  unsigned int padding = 16; /* Use minimum padding */

  hbtype = *p++;
  n2s(p, payload);  #2
  pl = p;  #3

  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);

  if (hbtype == TLS1_HB_REQUEST)
    {
    unsigned char *buffer, *bp;
    int r;

    buffer = OPENSSL_malloc(1 + 2 + payload + padding);  #4
    bp = buffer;

    *bp++ = TLS1_HB_RESPONSE;
    s2n(payload, bp);
    memcpy(bp, pl, payload);   #5
    bp += payload;
    RAND_pseudo_bytes(bp, padding);

    r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);

Inspect the vulnerable OpenSSL 1.0.1f path, especially attacker-controlled length parsing and the unchecked memcpy operation. section 10.6

Defensive implementation rules:

  • Treat client-supplied lengths as untrusted, validate buffer bounds before copying, and prefer functions that require explicit length limits. section 10.6
  • Recognize that memcpy is not inherently unsafe, but blindly copying attacker-controlled lengths can produce buffer overreads or overwrites. section 10.6

How Hacking Cryptography covers it

How deep it goes
Explains the normal exchange, traces the overread, and descends into vulnerable OpenSSL parsing and copying code.
Examples
Uses a 12-byte “good_morning” echo, an oversized malicious request, and OpenSSL 1.0.1f source code.
What it assumes
Assumes basic TLS and C/C++ buffer familiarity while defining heartbeat behavior and unchecked-copy risks concretely.
What you can do after
Diagnose buffer overreads by comparing declared payload lengths with supplied bytes and checking copy bounds.
How it connects
Connects TLS, memory safety, buffer overread, bounds checking, memcpy, and Heartbleed.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Hacking Cryptography. The section links point to the parts of the book it draws on.