fix(google): bound OAuth response reads to prevent OOM#99812
Conversation
Replace all unbounded response.arrayBuffer() and response.json() calls in Google OAuth HTTP paths with bounded SDK helpers (readResponseWithLimit, readProviderJsonResponse) that enforce configurable size caps. 7 call sites across 3 files fixed: - extensions/google/vertex-adc.ts: token refresh response - extensions/google/oauth.token.ts: token grant response - extensions/google/oauth.project.ts: userinfo, poll, and project discovery
|
ClawSweeper review: did not complete due to Codex infrastructure failure. Reviewed July 4, 2026, 1:28 AM ET / 05:28 UTC. Summary PR surface: Source +17. Total +17 across 3 files. Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path. Review metrics: none identified. Merge readiness This is a ClawSweeper/Codex infrastructure failure, not a PR readiness or patch-quality verdict. Risk before merge
Maintainer options:
Next step before merge
Review detailsBest possible solution: Retry the Codex review after fixing the execution failure. Do we have a high-confidence way to reproduce the issue? Unclear. The review failed before ClawSweeper could establish a reproduction path. Is this the best way to solve the issue? Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction. AGENTS.md: unclear because the file could not be read completely. Codex review notes: model internal, reasoning high; reviewed against 8822b66952b7. Label changesLabel changes:
Evidence reviewedPR surface: Source +17. Total +17 across 3 files. View PR surface stats
What I checked:
Likely related people:
How this review workflow works
|
Add maxOutputLength to gunzipSync so a small compressed token response cannot inflate past the 1 MB wire cap. Closes the decompression bomb path that the wire cap alone cannot address. Ref. openclaw#99812
|
@clawsweeper re-review Pushed commit f7745fc that adds maxOutputLength to gunzipSync and updated PR body with L2 loopback HTTP proof and decompression bomb demonstration. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
Source: #99812 Co-authored-by: 黄剑雄0668001315 <[email protected]>
* fix(agents): harden LSP process failures Source: #100450 Co-authored-by: morluto <[email protected]> * fix(sandbox): report effective workspace layout Sources: #100435, #100439 Co-authored-by: Aniruddha Adak <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> * fix(security): fail install checks on stream errors Source: #100413 Co-authored-by: 陈宪彪0668000387 <[email protected]> * fix(android): normalize all-day calendar events Source: #100032 Co-authored-by: NianJiuZst <[email protected]> * fix(ios): serialize push-to-talk lifecycle Source: #99942 Co-authored-by: NianJiuZst <[email protected]> * fix(talk): reject inherited provider names Source: #99849 Co-authored-by: zenglingbiao <[email protected]> * fix(android): stop voice capture in background Source: #99840 Co-authored-by: xialonglee <[email protected]> * fix(cron): preserve fallback result classification Source: #99913 Co-authored-by: jincheng-xydt <[email protected]> * fix(google): bound Vertex response decompression Source: #99812 Co-authored-by: 黄剑雄0668001315 <[email protected]> * fix(plugins): report malformed discovery JSON Source: #99892 Co-authored-by: 陈宪彪0668000387 <[email protected]> * test(sandbox): configure non-default workspace fixture * test: fix small-fix batch validation --------- Co-authored-by: morluto <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> Co-authored-by: 陈宪彪0668000387 <[email protected]> Co-authored-by: NianJiuZst <[email protected]> Co-authored-by: zenglingbiao <[email protected]> Co-authored-by: xialonglee <[email protected]> Co-authored-by: jincheng-xydt <[email protected]> Co-authored-by: 黄剑雄0668001315 <[email protected]>
|
Thanks @Pandah97 — your Vertex response-size finding was incorporated into the narrower canonical fix in #100483, landed as aaf5ab9. OAuth token/project responses are already bounded by the shared fetch helper, so the landed change targets the genuinely unbounded Vertex stream path and independently caps raw and gzip-decompressed output. Contributor credit is preserved. Closing this superseded PR. |
* fix(agents): harden LSP process failures Source: openclaw#100450 Co-authored-by: morluto <[email protected]> * fix(sandbox): report effective workspace layout Sources: openclaw#100435, openclaw#100439 Co-authored-by: Aniruddha Adak <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> * fix(security): fail install checks on stream errors Source: openclaw#100413 Co-authored-by: 陈宪彪0668000387 <[email protected]> * fix(android): normalize all-day calendar events Source: openclaw#100032 Co-authored-by: NianJiuZst <[email protected]> * fix(ios): serialize push-to-talk lifecycle Source: openclaw#99942 Co-authored-by: NianJiuZst <[email protected]> * fix(talk): reject inherited provider names Source: openclaw#99849 Co-authored-by: zenglingbiao <[email protected]> * fix(android): stop voice capture in background Source: openclaw#99840 Co-authored-by: xialonglee <[email protected]> * fix(cron): preserve fallback result classification Source: openclaw#99913 Co-authored-by: jincheng-xydt <[email protected]> * fix(google): bound Vertex response decompression Source: openclaw#99812 Co-authored-by: 黄剑雄0668001315 <[email protected]> * fix(plugins): report malformed discovery JSON Source: openclaw#99892 Co-authored-by: 陈宪彪0668000387 <[email protected]> * test(sandbox): configure non-default workspace fixture * test: fix small-fix batch validation --------- Co-authored-by: morluto <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> Co-authored-by: 陈宪彪0668000387 <[email protected]> Co-authored-by: NianJiuZst <[email protected]> Co-authored-by: zenglingbiao <[email protected]> Co-authored-by: xialonglee <[email protected]> Co-authored-by: jincheng-xydt <[email protected]> Co-authored-by: 黄剑雄0668001315 <[email protected]>
Summary
Problem: Three Google OAuth modules read HTTP response bodies without size limits, creating OOM risk when upstream services return oversized or malicious payloads. Additionally,
gunzipSyncin the Vertex ADC parser lacks a decompressed-output cap, so a small compressed payload can still inflate past the wire limit.Solution: Replace all unbounded
response.arrayBuffer(),.json()calls with bounded SDK helpers (readResponseWithLimit,readProviderJsonResponse). AddmaxOutputLengthtogunzipSyncto cap decompressed output at the same 1 MB bound.What changed:
extensions/google/vertex-adc.ts,extensions/google/oauth.token.ts,extensions/google/oauth.project.ts— 3 files, +27/-12 lines.gunzipSyncbounded viamaxOutputLength: GOOGLE_OAUTH_TOKEN_RESPONSE_MAX_BYTESWhat did NOT change: No behavior change for well-formed responses under the size limits. No API or config surface changes. No dependency additions.
What Problem This Solves
7 call sites across 3 files consume unbounded HTTP response bodies. This is the same unbounded-read class fixed across 30+ providers via the Plugin SDK, but the Google OAuth paths were missed.
Additionally, the Vertex ADC gzip decoder could amplify a small compressed payload (under the 1 MB wire cap) into an arbitrarily large decompressed buffer, leaving an OOM path open even after the wire cap.
Why This Change Was Made
The existing
readProviderJsonResponseandreadResponseWithLimithelpers already ship in the Plugin SDK with a default 16 MB cap. Using them here aligns with the established bounded-read pattern. ThemaxOutputLengthoption ongunzipSync(Node 15+) closes the decompression amplification path that the wire cap alone cannot address.Real behavior proof
Behavior addressed: Bounded HTTP response reads and bounded gzip decompression for Google OAuth HTTP paths.
BEFORE FIX — unbounded
response.arrayBuffer()reads entire body into memory:AFTER FIX — bounded read with 1 MB cap and overflow error:
BEFORE FIX — unbounded
gunzipSyncallocates full decompressed output:AFTER FIX — bounded decompression with
maxOutputLength:Real environment tested: Linux x86_64, Node v24.13.1.
Exact steps or command run after this patch:
After-fix evidence: L2 runtime proof with loopback HTTP server and decompression bomb:
Unit tests:
Observed result after the fix: All tests pass. Both loopback proof scripts confirm oversized responses and decompression bombs are safely rejected at the 1 MB boundary. Normal-sized responses pass through unchanged.
What was not tested: Actual Google OAuth HTTP round-trips (requires live credentials). The SDK helpers
readResponseWithLimitandreadProviderJsonResponseare integration-tested insrc/agents/provider-http-errors.test.tsandpackages/media-core/src/read-response-with-limit.test.ts. This PR only swaps the call sites and adds amaxOutputLengthoption, preserving all existing error handling and test seams.Risk checklist
merge-risk: Low
maxOutputLengthongunzipSync