"Scott L. Burson" Scott@sympoiesis.com writes:
On Wed, Apr 23, 2014 at 1:06 AM, Max Rottenkolber max@mr.gy wrote:
From what I understand about the bug (I have not seen the code) it sounds
like data length information
arrived both directly and indirectly in the client message and that a
conflict between them was not
scrutinized.
No. The bug was that the keep alive protocol in SSL mandates the server to echo arbitrary data back to the client. The bounds checks were wrong too, but at that stage it really doesn't matter. The design is just plain wrong.
It is a bit curious that the protocol mandates this echoing, and one could certainly debate whether this is good protocol design, but as far as the actual vulnerability goes, David's characterization is accurate. The heartbeat request arrives with some number of bytes of data attached to it, and also with a length field that tells the server how many bytes the client would like echoed back. There was no check that the client didn't request more bytes be echoed than it had actually sent.
This is not what the protocol specifies.
The protocol specifies that if the length mentionned is wrong ("too big"), then nothing should be answered, and otherwise that the exact payload data received be sent back.
Nowhere does it say that the length field in the packet has any validity that the server must use it blindly.
Nowhere is it specified that the server should return data beyond the payload data.
It is obvious that the message length should be taken ito account to determine the padding_length, since it's not in the message. This is explicitely described in the protocol specifications:
padding: The padding is random content that MUST be ignored by the receiver. The length of a HeartbeatMessage is TLSPlaintext.length for TLS and DTLSPlaintext.length for DTLS. Furthermore, the length of the type field is 1 byte, and the length of the payload_length is 2. Therefore, the padding_length is TLSPlaintext.length - payload_length - 3 for TLS and DTLSPlaintext.length - payload_length - 3 for DTLS. The padding_length MUST be at least 16.
The sender of a HeartbeatMessage MUST use a random padding of at least 16 bytes. The padding of a received HeartbeatMessage message MUST be ignored.