Fix/discord bound probe getme json reads#97278
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 28, 2026, 4:45 AM ET / 08:45 UTC. Summary PR surface: Source +4, Tests +37. Total +41 across 2 files. Reproducibility: yes. as source-reproducible: current main and Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the focused bounded-reader migration after exact-head checks finish, preferably with the PR body updated to match the final two-file diff. Do we have a high-confidence way to reproduce the issue? Yes, as source-reproducible: current main and Is this the best way to solve the issue? Yes. Reusing AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 9c95abd49d45. Label changesLabel justifications:
Evidence reviewedPR surface: Source +4, Tests +37. Total +41 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
cb46de5 to
61db18d
Compare
|
Land-ready verification for
The change stays behind the public plugin SDK, preserves fail-soft probe behavior, and has no remaining review findings. |
|
Merged via squash.
|
* fix(discord): bound probe getMe JSON response reads * test(discord): add oversized probe getMe JSON regression * test(discord): add loopback proof for bounded probe getMe reads * fix(scripts): satisfy oxlint in discord probe proof script * test(discord): keep probe proof in focused coverage --------- Co-authored-by: NIO <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
* fix(discord): bound probe getMe JSON response reads * test(discord): add oversized probe getMe JSON regression * test(discord): add loopback proof for bounded probe getMe reads * fix(scripts): satisfy oxlint in discord probe proof script * test(discord): keep probe proof in focused coverage --------- Co-authored-by: NIO <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
* fix(discord): bound probe getMe JSON response reads * test(discord): add oversized probe getMe JSON regression * test(discord): add loopback proof for bounded probe getMe reads * fix(scripts): satisfy oxlint in discord probe proof script * test(discord): keep probe proof in focused coverage --------- Co-authored-by: NIO <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
* fix(discord): bound probe getMe JSON response reads * test(discord): add oversized probe getMe JSON regression * test(discord): add loopback proof for bounded probe getMe reads * fix(scripts): satisfy oxlint in discord probe proof script * test(discord): keep probe proof in focused coverage --------- Co-authored-by: NIO <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
Discord health probes call
GET /users/@meand still parse the success body with unboundedres.json(). On Node,response.json()buffers the entire body before parsing, so a hostile or misbehaving Discord REST endpoint can stream an oversized success payload during gateway health checks and push the process into memory pressure or OOM.This closes the remaining unbounded Discord probe success read on current
main. Open PR#96618bounds other Discord REST success reads (PluralKit, webhook upload, voice upload) but explicitly leavesprobeDiscord()on the old path.No open upstream PR duplicates this surface.
Changes
readProviderJsonResponse(response, "discord.probe.getMe"), reusing the shared 16 MiB provider JSON reader instead of a plugin-local helper.ok: falsewith a formatted error string.ReadableStreamregression test with aresponse.json()sentinel.scripts/proof-discord-probe-bound.mjs, which drives exportedprobeDiscord()against a localnode:httpserver.Real behavior proof
/users/@meresponse with noContent-Lengthmust not be buffered whole if it exceeds the 16 MiB provider JSON cap; the probe must fail closed instead of draining the full body.node:httpon127.0.0.1, streaming ~24 MiB JSON in 64 KiB chunks with noContent-Length, driven through exportedprobeDiscord()with a fetcher redirected to the loopback server./users/@me.probeDiscord()and assertok: falsewith the labeled cap error while the server stops sending near the cap.readProviderJsonResponseagainst the same stream to confirm the shared reader stops early (negative control vs unbounded drain).probeDiscord()against a small valid body and confirm bot id/username parse intact.Evidence
Regression locked in:
Loopback HTTP proof (production
probeDiscordpath):Label: security
AI-assisted.