Heartbleed's Little Cousin — JavaScript Bug Hunt

Inspired by Heartbleed (2014): a heartbeat request says "echo 4 bytes back — no wait, echo 64,000" — and the server obliges, reading past the payload into…

  • Language: JavaScript
  • Layer: Backend
  • Difficulty: Hard
  • Concepts: Security, Bounds
  • Modelled on: OpenSSL · 2014
  • Visible tests: honest requests echo exactly; over-claimed lengths leak nothing; shorter claims truncate normally
  • Reward: 50 XP for a complete fix

Briefing

Inspired by Heartbleed (2014): a heartbeat request says "echo 4 bytes back — no wait, echo 64,000" — and the server obliges, reading past the payload into memory holding private keys.

The echo service (locked memory region included) must never return more bytes than the client actually sent.

Bug report

BUG-HB · Priority: Existential · Reported by: security

echo(payload, claimedLength):

  • return AT MOST payload.length bytes of the payload
  • the claimed length is untrusted client input

Observed: over-claimed lengths return the payload PLUS whatever sits next to it in the buffer — including the region marked SECRET.

Logs

[tls] heartbeat req len=4 claimed=64 -> response contains "SECRET_MASTER_KEY"

The code as shipped

src/tls/heartbeat.js (editable)

var memory = require("./memoryRegion");

// Echoes the heartbeat payload back to the client.
exports.echo = function (payload, claimedLength) {
  var buffer = payload + memory.ADJACENT_MEMORY;
  return buffer.slice(0, claimedLength);
};

Read-only context: src/tls/memoryRegion.js.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.