fix(google): bound OAuth project and token JSON response reads#97587
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 4, 2026, 10:13 PM ET / 02:13 UTC. Summary PR surface: Source +7, Tests +134. Total +141 across 3 files. Reproducibility: yes. Source inspection shows raw 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 this narrow parser-boundary hardening once maintainers accept the auth-provider fail-closed behavior, and review broader Vertex ADC hardening separately unless they choose a consolidated Google OAuth bundle. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows raw Is this the best way to solve the issue? Yes. With the shared fetch cap and token-error cap already on main, replacing the remaining parser sites with the existing SDK bounded JSON helper is the narrowest maintainable owner-boundary fix. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 7d3cfa85dca1. Label changesLabel justifications:
Evidence reviewedPR surface: Source +7, Tests +134. Total +141 across 3 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
Review history (4 earlier review cycles)
|
1a7d1ff to
0bb0e96
Compare
0bb0e96 to
09fef5a
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
09fef5a to
d7da56d
Compare
d7da56d to
63570bb
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Merge-ready from local maintainer review. Autoreview is clean at head SHA 63570bb, CI is green, and I found no compatibility concerns or breaking changes. This is the best narrow fix for the remaining Google OAuth JSON parse-boundary gap: it uses the existing 16 MiB provider JSON cap at the owning call sites while preserving normal OAuth behavior. |
Co-authored-by: NIO <[email protected]>
Co-authored-by: NIO <[email protected]>
What Problem This Solves
extensions/google/oauth.project.tsandextensions/google/oauth.token.tscontained sixunbounded
await response.json()calls on the Gemini CLI OAuth onboarding and token-exchangepaths (
getUserEmail,pollOperation,loadCodeAssistsuccess + error,onboardUser,requestTokenGrant).After
fetchWithTimeoutmaterialises the response body,response.json()can trigger asecond large allocation during
JSON.parse. Replacing these calls withreadProviderJsonResponsecaps the JSON parse step at 16 MiB with labeled errors at eachOAuth call site.
This complements the shared fetch boundary landed in #97628
(
readResponseWithLimitinsidefetchWithTimeout). Together the two layers give defense indepth:
JSON.parseon the bufferedResponseobjects thatOAuth call sites consume.
Changes
extensions/google/oauth.project.ts:readProviderJsonResponsefromopenclaw/plugin-sdk/provider-httpresponse.json()reads with labeledreadProviderJsonResponse(...)calls(
google.userinfo,google.poll-operation,google.load-code-assist,google.onboard-user)extensions/google/oauth.token.ts:readProviderJsonResponsefromopenclaw/plugin-sdk/provider-httpawait response.json()→readProviderJsonResponse(response, "google.token")in
requestTokenGrantextensions/google/oauth.test.ts:rejects an oversized token exchange response body(end-to-end viaexchangeCodeForTokens; fetch cap fires first after fix(google): bound google OAuth fetchWithTimeout arrayBuffer at 16 MiB #97628)rejects an oversized token body at the JSON parse boundary(defense-in-depth whenfetchWithTimeoutalready returned a buffered oversized body)rejects an oversized loadCodeAssist success response body(viaresolveGoogleOAuthIdentity)swallows bound error on oversized userinfo body and returns undefined emailRebased onto current
main; the stale plugin SDK surface budget commit was dropped because#97628 and other main commits already carry those values.
Real behavior proof
Behavior addressed: Oversized or hostile Google OAuth JSON responses fail closed instead
of triggering unbounded
JSON.parseallocation on buffered bodies returned byfetchWithTimeout.Real environment tested: Node v22, macOS 24.3.0,
node:httpstreaming server on127.0.0.1, built helpers fromdist/plugin-sdk/provider-http.jsanddist/plugin-sdk/response-limit-runtime.js.Exact steps:
Content-Length).readResponseWithLimitat the fetch boundary → assert labeled overflow error.readProviderJsonResponseon the same streamed body → assert labeled parse cap.response.bodyreader consumes the full ~18 MiB stream.fetchWithTimeoutbufferedResponseshape rejects at parse boundary..catch(() => null)swallows oversized error bodies.exchangeCodeForTokensandresolveGoogleOAuthIdentity.Observed result:
google HTTP fetch: body exceeds 16777216 bytes (got 16817603)google.token: JSON response exceeds 16777216 bytesJSON.parse.catch(() => null)returnsnullon oversized bodyALL PROOF ASSERTIONS PASSEDWhat was not tested: live Google OAuth API calls.
Evidence
New bound regression tests (4 added):
loginGeminiCliOAuth > rejects an oversized token exchange response body✓loginGeminiCliOAuth > rejects an oversized token body at the JSON parse boundary✓loginGeminiCliOAuth > rejects an oversized loadCodeAssist success response body✓loginGeminiCliOAuth > swallows bound error on oversized userinfo body and returns undefined email✓