Skip to content

fix(sandbox): cap the Go daemon's /grep result limit - #6180

Merged
pedrofrxncx merged 1 commit into
mainfrom
fix/daemon-grep-limit-cap-w1
Aug 18, 2026
Merged

fix(sandbox): cap the Go daemon's /grep result limit#6180
pedrofrxncx merged 1 commit into
mainfrom
fix/daemon-grep-limit-cap-w1

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Follows #6176 (which capped fs route request bodies): auditing packages/sandbox/daemon-go/internal/routes/fs.go for remaining size-limit loopholes found that /grep's caller-supplied limit had no upper bound, unlike /glob's resultLimit which is clamped to globMaxResultLimit.

Why it matters: a caller passing a very large limit makes the handler buffer that many rg match lines into memory before the daemon ever caps it, the same class of unbounded-memory-growth issue #6176 fixed for request bodies. Both close variants of the daemon getting killed mid-run by a missed health probe.

Fix: add grepMaxResultLimit (10000, matching Glob's cap) and clamp the effective limit to it, same pattern already used by Glob.

Regression test: TestGrepCapsCallerSuppliedLimit in fs_test.go seeds a file with more matching lines than the cap, requests a limit far above it, and asserts the response's matchCount never exceeds grepMaxResultLimit. It skips locally if rg isn't installed but runs for real in CI (sandbox-daemon.yml installs ripgrep).

Reviewer command: cd packages/sandbox/daemon-go && go test ./internal/routes/... -run TestGrepCapsCallerSuppliedLimit -v (needs ripgrep installed to actually exercise the cap; otherwise it self-skips).

Locally verified: go build ./..., go vet ./internal/routes/..., go test ./internal/routes/..., gofmt -l (clean) in packages/sandbox/daemon-go. Full CI (including the ripgrep-backed test run) validates the rest.


Summary by cubic

Caps the Go sandbox daemon’s /grep results at 10,000 and clamps caller-supplied limit to prevent unbounded memory usage. Previously /grep accepted any limit and could buffer arbitrarily many rg match lines; now it uses min(requested, 10,000), matching /glob.

  • Introduces grepMaxResultLimit (10000) and grepDefaultResultLimit (250); default behavior is unchanged, large limits are now clamped in packages/sandbox/daemon-go/internal/routes/fs.go.
  • Responses with more than 10,000 matches are truncated; clients should not rely on receiving more than 10,000 results.
  • Adds TestGrepCapsCallerSuppliedLimit in fs_test.go; run with: cd packages/sandbox/daemon-go && go test ./internal/routes/... -run TestGrepCapsCallerSuppliedLimit -v (requires ripgrep installed).

Written for commit ebd7eea. Summary will update on new commits.

Review in cubic

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.
@pedrofrxncx
pedrofrxncx merged commit 98e6873 into main Aug 18, 2026
27 checks passed
@pedrofrxncx
pedrofrxncx deleted the fix/daemon-grep-limit-cap-w1 branch August 18, 2026 15:59
decocms Bot pushed a commit that referenced this pull request Aug 18, 2026
PR: #6180 fix(sandbox): cap the Go daemon's /grep result limit
Bump type: patch

- @decocms/sandbox (packages/sandbox/package.json): 1.55.3 -> 1.55.4
- deploy/helm/sandbox-env (chart 0.16.5) (deploy/helm/sandbox-env/values.yaml deploy/helm/sandbox-env/Chart.yaml): image.tag/appVersion -> 1.55.4

Deploy-Scope: both
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant