fix(sandbox): cap the Go daemon's fs route request bodies - #6176
Merged
Conversation
pedrofrxncx
enabled auto-merge (squash)
August 18, 2026 14:40
decodeBody (used by every /fs/* route: read, write, edit, mkdir, unlink, mv, list, write_from_url, upload_to_url) read the request body with an unbounded io.ReadAll. A caller sending an oversized body could buffer it entirely into the daemon's memory and crash it, tearing down the sandbox pod on the next missed health probe. Cap it at maxTransferBytes (500MB), the same bound the daemon already uses for its other file-transfer path, following the same LimitReader pattern used to cap the JSON-RPC response body in #6162. Test: TestDecodeBodyRejectsOversizedRequest drives decodeBody with an infinite reader and asserts it rejects instead of buffering forever.
pedrofrxncx
force-pushed
the
fix/daemon-cap-fs-request-body-w3
branch
from
August 18, 2026 14:48
28964b0 to
11683c7
Compare
decocms Bot
pushed a commit
that referenced
this pull request
Aug 18, 2026
PR: #6176 fix(sandbox): cap the Go daemon's fs route request bodies Bump type: patch - @decocms/sandbox (packages/sandbox/package.json): 1.55.2 -> 1.55.3 - deploy/helm/sandbox-env (chart 0.16.4) (deploy/helm/sandbox-env/values.yaml deploy/helm/sandbox-env/Chart.yaml): image.tag/appVersion -> 1.55.3 Deploy-Scope: both
pedrofrxncx
added a commit
that referenced
this pull request
Aug 18, 2026
A caller-supplied `limit` on /grep had no upper bound, unlike /glob's matching globMaxResultLimit cap. A large limit lets rg's match lines accumulate in memory unbounded, the same crash-the-daemon DoS class #6176 closed for request bodies.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Source: a real resource-bound gap, in the same lane as #6162 (which capped the daemon's outbound MCP JSON-RPC response body) — this caps the daemon's inbound fs request body, which was still unbounded.
Why a maintainer wants this:
decodeBodyinpackages/sandbox/daemon-go/internal/routes/fs.gobacks every/fs/*route (read, write, edit, mkdir, unlink, mv, list, write_from_url, upload_to_url) and read the request body with a plainio.ReadAll(r.Body)— no size cap. A caller sending an oversized body could buffer it entirely into the daemon's memory and crash it. Per this repo's own docs, the daemon's health probe is unforgiving: Studio marks the sandbox dead on a single missed probe and tears the pod down mid-session, so an OOM here is a real availability hit, not just a slow request.Fix: cap the body at
maxTransferBytes(500MB) — the bound the daemon already uses for its other file-transfer path (write_from_url/upload_to_url) — via the sameio.LimitReader+ explicit length check pattern #6162 used for the JSON-RPC response cap.Regression test:
TestDecodeBodyRejectsOversizedRequestinfs_test.godrivesdecodeBodywith aninfiniteReader(never hits EOF, no upfront allocation) and asserts it returns a size-limit error instead of buffering forever.To verify:
cd packages/sandbox/daemon-go && go test ./internal/routes/... -run TestDecodeBodyRejectsOversizedRequest -vChecks run locally:
go build ./...,go vet ./internal/routes/...,gofmt -l(clean), and the targeted test above (passes, ~0.5s). Full CI covers the rest.Summary by cubic
Caps the Go daemon’s /fs/* request bodies at 500MB to prevent OOM and sandbox teardown. Previously
decodeBodyread an unbounded body withio.ReadAll; now it wraps the body withio.LimitReader(maxTransferBytes+1)and rejects payloads overmaxTransferBytes.TestDecodeBodyRejectsOversizedRequestusing an infinite reader to verify rejection without buffering.Written for commit 11683c7. Summary will update on new commits.