Skip to content

[audit] Unbounded reads / responses / buffers without a byte cap #6554

Description

@7jrxt42BxFZo4iAnN4CX

Source: static audit of main@384439634. Candidates are static and not reproduced — confirm each before changing code.
Template: agent-task (agent-ready, docs/ISSUE_TRIAGE.md). Labels: bug, agent-ready.

Goal / Why

Network responses, files, child pipes, and artifact reads are consumed with .text()/read_to_string/read_to_end (or a growing buffer) before any size bound. A single oversized response, artifact, or pipe can OOM the process or wedge a worker, and several paths buffer the whole body before they even consult the configured cap. The sources differ (HTTP, filesystem, child stdin/stdout, artifact store) but the failure mode is the same and the fix is one bounded reader. Apply a byte cap with a truncation note at ingest, not after materialising content.

Confirmed static findings in this class: 23 (reassessed severity noted per line).

Scope / Plan

  1. Re-read each candidate below at the cited file:line on current main; drop anything already fixed or misread.
  2. Apply a bounded reader (byte cap + truncation note) at every listed site before materialising content; add a regression test per reader.
  3. Add the smallest regression/gate that would catch a re-introduction (focused test, budget script, or grep guard).

Key files

  • crates/tui/src/tools/web_run.rs
  • crates/tui/src/skills/audit.rs
  • crates/tui/src/skills/mod.rs
  • crates/tui/src/skills/install.rs
  • crates/tui/src/repl/runtime.rs
  • crates/tui/plugins/computer-use/mcp/server.mjs
  • crates/tui/src/tui/diff_render.rs
  • crates/tui/src/tui/history/tool_output.rs
  • crates/tui/src/tui/widgets/workflow_panel.rs
  • crates/tui/src/tools/fetch_url.rs
  • crates/tui/src/tools/truncate.rs
  • crates/tui/src/tools/tool_result_retrieval.rs
  • crates/tui/src/client/anthropic.rs
  • crates/tui/src/client/responses.rs

Acceptance criteria

  • Every listed candidate is either fixed with a test, or downgraded with a written reason in the PR.
  • No new instance of this class is introduced (guarded by the test/budget).
  • Existing behavior for unrelated paths is unchanged.

Verification

cargo check -p codewhale-tui -p codewhale-cli -p codewhale-release -p codewhale-telemetry -p codewhale-workflow-js
cargo test  -p codewhale-tui --lib
cargo clippy --workspace --all-targets --locked -- -D warnings
( cd web && npm run check )
( cd integrations/bridge-core && npm run test )

Out of scope

  • Findings that belong to another systemic class or to the localized backlog.
  • Re-architecture beyond the listed sites.

Related existing work (do not duplicate)

#6147 (bound engine channels), #6333 (read budgets), #6504 (sub-agent input cap), #6540 (compaction), #5404/#5468 (SSE tail fail-closed)

Candidate findings (23)

  • D03-07 · D03 — Git/GitHub/review/web tools · crates/tui/src/tools/web_run.rs:367 — operation fan-out and .text() bodies are unbounded; one model call can exhaust memory/network.
    audit severity: high; reassessed: major
  • F02-02 · F02 — Skills, hooks, LSP, snapshots, REPL, RLM, work graph · crates/tui/src/skills/audit.rs:426, crates/tui/src/skills/mod.rs:503 — special/unbounded files can hang/OOM audit/discovery.
    audit severity: high; reassessed: major
  • F02-04 · F02 — Skills, hooks, LSP, snapshots, REPL, RLM, work graph · crates/tui/src/skills/install.rs:557 — remote download fully buffers response before the max_size check.
    audit severity: high; reassessed: major
  • F02-06 · F02 — Skills, hooks, LSP, snapshots, REPL, RLM, work graph · crates/tui/src/repl/runtime.rs:292 — stdout unbounded and stderr drained after round, allowing OOM/deadlock.
    audit severity: high; reassessed: major
  • CU01-09 · CU01 — Computer-use · crates/tui/plugins/computer-use/mcp/server.mjs:1319 — JSON-lines/socket/CDP frames and screenshots unbounded.
    audit severity: high; reassessed: major
  • U04-01 · U04 — History, transcript, markdown, diff, streaming · crates/tui/src/tui/diff_render.rs:49, crates/tui/src/tui/history/tool_output.rs:379 — huge tool output/diff materializes all wrapped rows and unbounded summary before head/tail.
    audit severity: high; reassessed: major
  • U05-03 · U05 — Work surface, widgets, agent cards/panels · crates/tui/src/tui/widgets/workflow_panel.rs:777 — attacker child_count causes huge allocation/OOM.
    audit severity: high; reassessed: major
  • D01-08 · D01 — Shell/file/read/search tools · crates/tui/src/tools/fetch_url.rs:520 — JSONPath fan-out does not bound fields/matches/serialized result.
    audit severity: major; reassessed: major
  • D01-09 · D01 — Shell/file/read/search tools · crates/tui/src/tools/truncate.rs:530 — on artifact publication failure the original unbounded result returns to model context.
    audit severity: major; reassessed: major
  • D01-10 · D01 — Shell/file/read/search tools · crates/tui/src/tools/tool_result_retrieval.rs:137 — retrieval fully reads artifact before applying max_bytes; a single giant line already bloats memory.
    audit severity: major; reassessed: major
  • T02-05 · T02 — Model HTTP/SSE clients · crates/tui/src/client/anthropic.rs:314, crates/tui/src/client/responses.rs:258 — endless small SSE chunks bypass idle timer and grow buffer without cap.
    audit severity: major; reassessed: major
  • T04-11 · T04 — Config, credentials, sandbox, trust · crates/tui/src/sandbox/opensandbox.rs:94 — response body unbounded/raw, cancellation is not propagated to remote exec.
    audit severity: major; reassessed: major
  • T05-09 · T05 — Runtime API, ACP, control socket, web/mobile · crates/tui/src/acp_server.rs:94 — ACP lines/text/tool JSON/history unbounded, invalid UTF-8 terminates server.
    audit severity: major; reassessed: major
  • T05-11 · T05 — Runtime API, ACP, control socket, web/mobile · crates/tui/src/runtime_api.rs:841 — managed Fleet does not limit task count/aggregate workflow size.
    audit severity: major; reassessed: major
  • U07-07 · U07 — Pickers, navigation, clipboard, keys · crates/tui/src/tui/file_frecency.rs:132 — sync global-mutex FS, no per-workspace key, unbounded JSONL.
    audit severity: major; reassessed: major
  • R02-03 · R02 — CLI, build-support, release/update · crates/cli/src/update.rs:1561, crates/release/src/lib.rs:256 — .bytes/.text unbounded and raw error body printed to terminal.
    audit severity: major; reassessed: major
  • R05-07 · R05 — Core, memory, telemetry client/ingest · crates/telemetry/src/actor.rs:75 — Unbounded telemetry queue + append/sync per event allows memory pressure.
    audit severity: major; reassessed: major
  • R05-08 · R05 — Core, memory, telemetry client/ingest · crates/telemetry/src/buffer.rs:246 — Telemetry buffer read_to_string unbounded and fails on invalid UTF-8.
    audit severity: major; reassessed: major
  • R06-07 · R06 — Lane, Workflow IR/VM, checked-in workflows · crates/workflow-js/src/vm.rs:199 — Untrusted source/args unbounded before QuickJS; recursive Fleet validation before depth cap; textual workflow decoy.
    audit severity: major; reassessed: major
  • U06-m1 · U06 — Ambient, pet watch, ocean, notifications · crates/tui/src/tui/gate_receipts.rs:51 — Auto-Review risk unbounded/control-containing.
    audit severity: minor; reassessed: medium
  • W01-05 · W01 — Website public pages/components/i18n · web/app/[locale]/digest/page.tsx:48 — Malformed KV sections:null fails; list/reads/sections unbounded.
    audit severity: major; reassessed: major
  • W01-08 · W01 — Website public pages/components/i18n · web/lib/deepseek.ts:28 — LLM request without timeout and unbounded error res.text().
    audit severity: major; reassessed: major
  • X01-09 · X01 — npm, SDK, VS Code, bridges, verifier · integrations/bridge-core/src/lib.mjs:430 — SSE only newline-newline, unbounded buffer, EOF accepted without terminal/thread identity.
    audit severity: high; reassessed: high

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageNew external report awaiting maintainer triage; repro, logs and version output help

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions