Skip to content

fix(sandbox): bound daemon config-PUT error body reads - #5334

Merged
pedrofrxncx merged 1 commit into
mainfrom
fix/bound-sandbox-config-error-body-w1
Jul 28, 2026
Merged

fix(sandbox): bound daemon config-PUT error body reads#5334
pedrofrxncx merged 1 commit into
mainfrom
fix/bound-sandbox-config-error-body-w1

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Follows #5316/#5319/#5330, which capped every upstream response read in sandbox-proxy.ts's proxyDaemon helper against the sandbox daemon's /_sandbox/config endpoint (and others) to prevent an unbounded body from being buffered fully into the API process's memory.

Three call sites that PUT directly to /_sandbox/config outside that proxy path were missed: patch-sandbox-operator.ts (runs on every publish/rebase), sync-git-credentials.ts (runs on every publish that pushes to GitHub), and resolve-env.ts (runs on sandbox start). Each reads the daemon's error body via a plain res.text() with no size cap on the non-ok path, so a compromised or misbehaving daemon can still make the Studio API process buffer an unbounded body into memory on this path — the exact concern the prior three PRs addressed for every other route.

Failure scenario: a sandbox daemon (attacker-controlled or just buggy) returns a huge body with a non-2xx status from /_sandbox/config; any of the three call sites (hit on essentially every publish, rebase, or sandbox start) reads it fully into memory with no ceiling, unlike every other route to the same endpoint.

Fix: extracted the existing readBoundedText/UpstreamPayloadTooLargeError helper out of sandbox-proxy.ts into apps/api/src/lib/bounded-text.ts (pure move, no behavior change — avoids an api-routes -> tools-layer import), and switched all three call sites to it with the same 10MB cap sandbox-proxy.ts already applies to this endpoint.

To verify: cd apps/api && bunx tsc --noEmit (clean) and bun test apps/api/src/api/routes/sandbox-proxy.test.ts apps/api/src/tools/sandbox/sync-git-credentials.test.ts (14 pass, 0 fail) — both cover the moved/consuming code.

Locally ran: bun run fmt, the targeted typecheck above, and the two targeted test files above. Full CI covers the rest.


Summary by cubic

Bounds error-body reads on direct PUTs to the sandbox daemon /_sandbox/config to prevent unbounded memory usage in the API process. Applies the same 10 MB cap used by the proxy and centralizes the helper.

  • Bug Fixes

    • Cap non-2xx body reads from /_sandbox/config in patch-sandbox-operator.ts, sync-git-credentials.ts, and resolve-env.ts via readBoundedText (10 MB).
    • Stops a compromised or buggy daemon from forcing huge error bodies into memory.
  • Refactors

    • Move readBoundedText and UpstreamPayloadTooLargeError to apps/api/src/lib/bounded-text.ts (no behavior change).
    • Update sandbox-proxy.test.ts imports to use the new lib.

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

Review in cubic

apps/api/src/tools/sandbox/{patch-sandbox-operator,resolve-env,sync-git-credentials}.ts
each PUT to the daemon's /_sandbox/config and, on a non-ok response, read the
error body with a plain res.text() with no size cap. sandbox-proxy.ts already
bounds every proxied response to the same endpoint via readBoundedText()
(#5316/#5319/#5330) — these three call sites hit /_sandbox/config directly
(during publish, rebase, and sandbox start) and were missed, so a
compromised or misbehaving daemon can still make the API process buffer an
unbounded error body into memory on that path.

Extracted readBoundedText()/UpstreamPayloadTooLargeError out of
sandbox-proxy.ts into apps/api/src/lib/bounded-text.ts (no behavior change)
so the tools/sandbox call sites can reuse it without an api-routes ->
tools-layer dependency, and switched all three sites to it with the same
10MB cap sandbox-proxy.ts already applies to this endpoint.
@pedrofrxncx
pedrofrxncx merged commit 478a4f3 into main Jul 28, 2026
15 checks passed
@pedrofrxncx
pedrofrxncx deleted the fix/bound-sandbox-config-error-body-w1 branch July 28, 2026 15:38
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