Skip to content

fix(chutes-oauth): bound core helper JSON response reads at 16 MiB#96777

Merged
vincentkoc merged 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/chutes-oauth-core-bounded-read
Jun 29, 2026
Merged

fix(chutes-oauth): bound core helper JSON response reads at 16 MiB#96777
vincentkoc merged 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/chutes-oauth-core-bounded-read

Conversation

@wangmiao0668000666

@wangmiao0668000666 wangmiao0668000666 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

src/agents/chutes-oauth.ts had 3 unbounded await 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 no Content-Length and 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.ts is covered by sibling PR #96779).

Changes

No new abstraction — reuses the existing readProviderJsonResponse helper from openclaw/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 Type calls with readProviderJsonResponse<Type>(response, "<label>"). Labels: "Chutes userinfo", "Chutes token exchange", "Chutes token refresh". (+6/-5)

Design Rationale

Why readProviderJsonResponse instead of response.json()? response.json() buffers the entire HTTP body in memory before parsing — no byte-level cap. readProviderJsonResponse reads 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

  • Behavior addressed: 3 unbounded response.json() calls → capped at 16 MiB via shared SDK helper.
  • Real environment tested: real node:http server (127.0.0.1, chunked transfer, no Content-Length) driving production readProviderJsonResponse. Node v22.22.0.
  • Exact steps or command run after this patch:
    node --import tsx _proof_chutes_oauth_core.mts
  • Evidence after fix: 4/4 assertions pass. AFTER: hostile 32 MiB body triggers bounded overflow error, valid token/userinfo responses parse correctly. BEFORE: unbounded read consumes 32.0 MiB (OOM vector confirmed).
  • Observed result after fix: 4/4 assertions pass. Hostile 32 MiB body triggers bounded overflow error at 16 MiB. Valid token exchange and userinfo responses parse correctly. Negative control: unbounded read consumed 32.0 MiB — cap is load-bearing.
  • Negative control: unbounded read consumed 32.0 MiB — proves the cap is load-bearing.
  • What was not tested: live Chutes API call (the proof exercises the same production SDK helper against the same attack shape); cross-platform Node differences.

Out of scope

Risk checklist

  • User-visible behavior change? No — normal-sized responses unaffected; oversized responses now throw a clear overflow error instead of silently accumulating memory.
  • Config/env/migration change? No — 16 MiB is the SDK helper default; no new config options.
  • Security/auth/secrets/network/tool-execution change? Yes — OOM/DoS protection for Chutes OAuth core helper userinfo, token exchange, and token refresh paths.
  • Highest-risk area: accidentally rejecting a legitimate response larger than 16 MiB; covered by the happy path assertion and the 6 existing tests.

Diff stats

1 file changed, 6 insertions(+), 5 deletions(-)

AI-assisted: implemented and proof-tested with AI assistance; reviewed by a human before submission.

@wangmiao0668000666
wangmiao0668000666 requested a review from a team as a code owner June 25, 2026 12:36
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS labels Jun 25, 2026
@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 27, 2026, 5:22 AM ET / 09:22 UTC.

Summary
The PR replaces the three Chutes core OAuth success-response JSON parses in src/agents/chutes-oauth.ts with the shared bounded provider JSON reader.

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.

  • Core Chutes Success-Body Reads Capped: 3 changed, 0 config/default surfaces added. This names the exact auth-provider behavior maintainers are accepting without adding an operator-facing setting.

Root-cause cluster
Relationship: canonical
Canonical: #96777
Summary: This PR is the canonical current split for Chutes core-helper bounded success-body reads; the active plugin path is a companion, not a replacement.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Add a focused Chutes core overflow regression test if maintainers want CI-captured coverage before merge.

Risk before merge

  • [P1] Merging intentionally changes oversized Chutes core OAuth userinfo, token exchange, and token refresh success bodies from unbounded buffering to labeled failure above 16 MiB.
  • [P1] The active bundled Chutes plugin OAuth path is separate and remains in fix(chutes-oauth-plugin): bound plugin JSON response reads at 16 MiB #96779, so maintainers may want to coordinate both Chutes surfaces.
  • [P1] No Chutes-specific oversized success-body regression test is committed in this branch; reviewer confidence comes from the shared helper contract, existing flow tests, CI, and PR-body terminal proof.

Maintainer options:

  1. Accept The Core OAuth Cap (recommended)
    Land this PR after exact-head gates if maintainers accept Chutes core token, userinfo, and refresh success bodies over 16 MiB failing closed.
  2. Ask For Chutes-Specific CI Coverage
    Request a focused regression test for the three Chutes core overflow labels if maintainers want this proof captured in committed tests before merge.
  3. Coordinate With The Plugin Companion
    Pause only if maintainers want deprecated core-helper and active plugin OAuth hardening to land together.

Next step before merge

  • [P2] Maintainer review should decide whether to accept the auth-provider cap and coordinate with the companion plugin PR; no automated code repair is needed.

Security
Cleared: No new security or supply-chain concern was found; the diff reduces provider-controlled unbounded JSON success reads without changing dependencies, scripts, permissions, secrets, or CI.

Review details

Best 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 readProviderJsonResponse is the narrowest maintainable fix for this scoped core-helper issue and avoids adding a one-off Chutes reader; the active plugin path is correctly handled as companion work.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against c5d34c8376f8.

Label changes

Label justifications:

  • P2: This is focused auth-provider memory-safety hardening with limited blast radius and no evidence of an active outage.
  • merge-risk: 🚨 auth-provider: The diff changes Chutes OAuth token, userinfo, and refresh success-response handling to fail closed above the shared provider JSON cap.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body contains terminal after-fix proof from a real local Node HTTP server, including oversized-body overflow, valid response parsing, and a before/negative-control comparison.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body contains terminal after-fix proof from a real local Node HTTP server, including oversized-body overflow, valid response parsing, and a before/negative-control comparison.
Evidence reviewed

PR surface:

Source +1. Total +1 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 6 5 +1
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 6 5 +1

What I checked:

Likely related people:

  • FrieSei: Git history shows Friederike Seiler authored the original Chutes OAuth helper that contains the core token exchange, userinfo, and refresh paths. (role: introduced behavior; confidence: high; commits: 4efb5cc18efa; files: src/agents/chutes-oauth.ts, src/commands/chutes-oauth.ts)
  • steipete: Git history shows Peter Steinberger merged and hardened the original Chutes OAuth work shortly after introduction. (role: merger and adjacent hardening contributor; confidence: high; commits: 8d640ccc6895, f566e6451f7e; files: src/agents/chutes-oauth.ts, src/commands/chutes-oauth.ts)
  • Viz: The OAuth refresh serialization work substantially maintains the auth-profile runtime path that calls refreshChutesTokens. (role: adjacent auth runtime contributor; confidence: medium; commits: 8e79080bef7d; files: src/agents/auth-profiles/oauth.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jun 25, 2026
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.
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@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.

@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@vincentkoc
vincentkoc merged commit f83cdec into openclaw:main Jun 29, 2026
108 of 111 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants