diff options
| author | Bitflash <btf01@proton.me> | 2026-07-28 15:25:57 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-28 15:25:57 -0300 |
| commit | 63764708903cf93476b0fa43580e23ff75ffceba (patch) | |
| tree | 7825001b9037531ee625edd38b9cf177bc0300d0 /src/script.h | |
| parent | 8a613d756c25983588c6ccabf3752aa31a4e7cb2 (diff) | |
rpc: bound and guard the Stratum surface (#19)
Everything an unauthenticated socket can reach in the pool server, in one
pass.
A line that never ends. RecvLine appended to the per-miner buffer and
looked for a newline; a peer that sends bytes and no newline grew that
buffer for as long as it kept writing, before authorizing or subscribing.
Capped at 64 KB, which drops the miner.
No limit on connections. Every accepted socket became a Miner with its
own buffer and nothing bounded the list. Capped at 1000.
Malformed requests crashed the node, not just the pool. ThreadRPCServer
has no exception handler, so anything thrown from line handling reached
the top of the thread and terminated the process. Three ways in, all
valid JSON that parses cleanly:
[1,2,3] -- value() on a non-object throws
{"method": 1} -- value() with the wrong type throws
submit with params [1,2,3] -- get<std::string>() on a number throws
mining.authorize had the subtler shape of the same thing: it tested
p.size() without testing p.is_array(), and indexing a json object with a
number throws while size() happily returns its key count.
Each is now rejected on its own terms, and the call is wrapped so a throw
drops that miner instead of the node.
Diffstat (limited to 'src/script.h')
0 files changed, 0 insertions, 0 deletions