The Pointer That Ran Past the Buffer — JavaScript Bug Hunt
Modelled on Cloudbleed (Cloudflare, February 2017): an HTML rewriter checked for the end of its buffer with == instead of >=.
- Language: JavaScript
- Layer: Backend
- Difficulty: Medium
- Concepts: Memory Safety, Off-by-One
- Modelled on: Cloudflare · Cloudbleed 2017
- Visible tests: stops at the terminator; a region without a terminator stops at its own end
- Reward: 50 XP for a complete fix
Briefing
Modelled on Cloudbleed (Cloudflare, February 2017): an HTML rewriter checked for the end of its buffer with == instead of >=. When a page ended in just the wrong way the pointer stepped past the terminator, and the parser kept reading — spraying adjacent memory, including other customers' cookies and private messages, into public responses.
scanner.js walks a buffer looking for a terminator byte and returns everything before it. Its end check has the same flaw.
Fix scan so it can never read past the end of the buffer.
Bug report
BUG-CB17 · Priority: Critical (data leak) · Reported by: security
scan(arena, length, terminator):
arenais a shared backing store; this request owns only its firstlengthbytes, and everything after that belongs to other requests- returns the owned bytes before the first
terminator - if the terminator is absent within the owned region, returns all
lengthof them
Observed: the loop bounds itself on the ARENA size rather than on length, so a request whose region has no terminator keeps reading into the next request's bytes and returns them.
Logs
[rewriter] scan overran: length=3 returned=6
[rewriter] response contained bytes from an unrelated requestThe code as shipped
src/parser/scanner.js (editable)
// Reads owned bytes up to (but not including) the terminator.
exports.scan = function (arena, length, terminator) {
var out = [];
var p = 0;
// Stop when we reach the end of the backing store.
while (p < arena.length) {
if (arena[p] === terminator) return out;
out.push(arena[p]);
p++;
}
return out;
};
Read-only context: src/parser/README.js.
Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.