fix(chutes-oauth): bound core helper JSON response reads at 16 MiB#96777
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 27, 2026, 5:22 AM ET / 09:22 UTC. Summary PR surface: Source +1. Total +1 across 1 file. Reproducibility: yes. Current source and v2026.6.10 show the three unbounded success-body reads, and the PR body gives after-fix terminal proof with an oversized local Node HTTP response plus happy-path and before comparisons; this read-only review did not run tests. 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 narrow core-helper cap after maintainer acceptance of the 16 MiB auth-provider failure mode and decide whether to coordinate it with the companion plugin OAuth hardening. Do we have a high-confidence way to reproduce the issue? Yes. Current source and v2026.6.10 show the three unbounded success-body reads, and the PR body gives after-fix terminal proof with an oversized local Node HTTP response plus happy-path and before comparisons; this read-only review did not run tests. 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 c5d34c8376f8. Label changesLabel justifications:
Evidence reviewedPR surface: Source +1. Total +1 across 1 file. 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
|
Replace 3 unbounded (await response.json()) calls in the deprecated core chutes-oauth helper with readProviderJsonResponse (16 MiB cap). Sites: fetchChutesUserInfo (userinfo), exchangeChutesCodeForTokens (token exchange), refreshChutesTokens (token refresh). Reuses the existing SDK helper already used by 15+ other providers.
0f8c091 to
f6c85df
Compare
|
@clawsweeper re-review Rebased to latest main (fixes CI). Upgraded proof to 🦞-grade: added BEFORE (unbounded) comparison showing 32.0 MiB OOM vector confirmed, bytes-sent quantification, sibling PR references (#96249, #96723), and AI disclosure. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
@clawsweeper re-review 🦞 upgrades applied (PR body only):
No code changes. |
What Problem This Solves
src/agents/chutes-oauth.tshad 3 unboundedawait response.json()calls (userinfo fetch, token exchange, token refresh). A hostile Chutes endpoint, proxy, or CDN can return an oversized HTTP 200 JSON body with noContent-Lengthand stream an arbitrarily large payload —response.json()buffers everything into memory before parsing, making this an OOM vector on a path that runs with user-attached OAuth credentials.This is the JSON bounded-read analogue for the deprecated core Chutes helper (the active plugin path at
extensions/chutes/oauth.tsis covered by sibling PR #96779).Changes
No new abstraction — reuses the existing
readProviderJsonResponsehelper fromopenclaw/plugin-sdk/provider-http(16 MiB default cap, same helper used by 15+ provider plugin bounded-read PRs).src/agents/chutes-oauth.ts:119,159,230— replace 3(await response.json()) as Typecalls withreadProviderJsonResponse<Type>(response, "<label>"). Labels:"Chutes userinfo","Chutes token exchange","Chutes token refresh". (+6/-5)Design Rationale
Why
readProviderJsonResponseinstead ofresponse.json()?response.json()buffers the entire HTTP body in memory before parsing — no byte-level cap.readProviderJsonResponsereads the body as a bounded stream, cancelling the underlying reader at 16 MiB (the SDK default) and throwing a canonical overflow error. This is the same pattern used by 15+ bounded-read PRs across the codebase.Why the same 16 MiB cap for all three calls (userinfo, token exchange, token refresh)? All three endpoints serve JSON OAuth payloads of comparable size (typically < 1 KiB). Using the same threshold avoids introducing per-endpoint cap distinctions with no operational benefit. The deprecated helper is being replaced by the plugin path (#96779); keeping the cap consistent simplifies eventual removal.
Why no inline test additions? The deprecated helper (
src/agents/chutes-oauth.ts) has 6 existing tests covering all three endpoints. The proof exercises the exact production helper with a real HTTP server, verifying overflow behavior. Adding inline tests would duplicate the helper's existing test coverage.Real behavior proof
response.json()calls → capped at 16 MiB via shared SDK helper.node:httpserver (127.0.0.1, chunked transfer, no Content-Length) driving productionreadProviderJsonResponse. Node v22.22.0.Out of scope
extensions/chutes/oauth.ts(active plugin path) — covered by sibling PR fix(chutes-oauth-plugin): bound plugin JSON response reads at 16 MiB #96779.response.json()call sites in core — covered by bounded-read campaign PRs (fix(image-generation): replace unbounded response.json() with readProviderJsonResponse #96776, fix(googlechat): replace unbounded response.json() with readProviderJsonResponse #96772, fix(video-generation): bound dashscope JSON response reads at 16 MiB #96782, etc.).Risk checklist
Diff stats
AI-assisted: implemented and proof-tested with AI assistance; reviewed by a human before submission.