2026-07-05
RFC 6520 is one of the most infamous RFCs in modern computing history — not because of what it says, but because a single implementation bug against its message format became the vulnerability the world knows as Heartbleed. Understanding the RFC illuminates how a well-intentioned three-page extension caused an internet-wide catastrophe in April 2014.
The problem it solves: DTLS runs TLS-like security over unreliable datagram transports (UDP, SCTP). Unlike TCP, there's no built-in liveness signal. If a peer disappears, you might not notice until your next application write fails — potentially minutes later. Worse, DTLS uses expensive rekeying and path MTU discovery that need a way to probe the peer. Traditional TLS solved this with full renegotiation, which is heavy. The Heartbeat extension introduces a lightweight keep-alive and PMTU discovery mechanism inside the encrypted channel.
The design: A new TLS content type (24 = heartbeat) carries two message types: HeartbeatRequest and HeartbeatResponse. The wire format is elegant in its simplicity:
type (1 byte) — request or responsepayload_length (2 bytes) — length of the payload the sender chosepayload — arbitrary bytes the responder must echo backpadding — at least 16 random bytesThe receiver echoes the payload verbatim, generates fresh padding, and sends it back. This confirms liveness and — critically — discovers PMTU: if a large heartbeat gets through, so will other datagrams of that size.
The bug that ate the internet: OpenSSL's implementation trusted the payload_length field without checking it against the actual received record size. An attacker could send a heartbeat with a 1-byte payload but claim payload_length = 65535. OpenSSL would memcpy 65535 bytes from its heap into the response — leaking whatever happened to be adjacent in memory: session keys, private keys, passwords, tokens. Two lines of missing bounds-checking. The RFC itself said in §4: "If the payload_length of a received HeartbeatMessage is too large, the received HeartbeatMessage MUST be discarded silently." The words were there. The check wasn't.
Interesting history: Robin Seggelmann, then a PhD student at Münster, wrote both the RFC and the OpenSSL patch, submitted on New Year's Eve 2011. Reviewer Stephen Henson merged it. Neither caught the bounds error. It shipped in OpenSSL 1.0.1 in March 2012 and lay dormant for two years until Neel Mehta at Google and Codenomicon independently found it. The subsequent fallout drove the creation of the Core Infrastructure Initiative, which funded critical open-source security work, and directly motivated LibreSSL's fork of OpenSSL.
Why it matters today: Heartbeat is now disabled by default in most TLS libraries, and TLS 1.3 dropped the extension entirely. But the lesson persists — length fields provided by an attacker must never be trusted against a separate buffer size. This pattern (declared length ≠ actual length) still causes vulnerabilities in QUIC, protobuf, and countless custom protocols. RFC 6520 is required reading not for its protocol design, but as a case study in how a semantically clear spec, implemented by a competent author, can still produce a catastrophic bug when a bounds check is skipped.
