HarperFast / HarperFast/harper
Unbounded per-subscriber realtime event queue: a slow/stalled subscriber grows server heap without limit (DoS)
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Summary
The realtime event-delivery path (per-subscriber event queue reached via `Table.send()`) has no high-water / backpressure cap. A subscriber (SSE / WebSocket / MQTT) that reads slowly or stalls, combined with a high write rate on the subscribed table, causes the server to buffer that subscriber's events in heap without limit. On socket teardown the buffered queue is not released.
## Impact
- Per-subscriber server heap grows roughly linearly with writes-while-stalled. Blast radius is **self-only** — healthy subscribers are unaffected (no head-of-line blocking).
- A deliberately-stalled subscriber under high write volume, or many naturally-slow subscribers (e.g. slow mobile clients), can drive the process toward OOM.
- Teardown does not release the buffered queue, so the growth persists after the slow subscriber disconnects.
## Suggested direction
- Add a high-water cap to the realtime per-subscriber queue, with a drop-oldest or disconnect-slow-consumer policy on overflow (the backpressure/`waitForDrain` mechanism that exists on the audit-replay path is not applied here).
- Release the queue on socket teardown.
## Scope
- Confirmed on SSE and WebSocket. MQTT QoS-1 persistent-session parity to be confirmed.
_Detailed reproduction, heap measurements, and code references are in the private Security Notes for this issue._
Contributor guide
Research direction
Start at the per-subscriber queue reached through Table.send() and compare the realtime delivery path with the audit-replay backpressure/waitForDrain mechanism. Inspect SSE and WebSocket teardown handling, then confirm MQTT QoS-1 persistent-session parity. Done means the queue is bounded with an overflow policy and is released on socket teardown, validated against the private reproduction and heap measurements.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nodejs
- Domain
- backend, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100