Repository navigation
Description
Summary
Terminal HTTP and RPC clients do not consistently enforce internal deadlines or response-size limits. The shared request cache also removes the caller signal before starting its deduplicated fetch, so a request that never settles can remain in the global in-flight map for the lifetime of the page even after every caller detaches.
Affected paths
apps/terminal/src/data/core/client.tsapps/terminal/src/data/core/cache.tsapps/terminal/src/protocols/support/provider.ts- Direct AVNU and Vesu fetch boundaries
- Terminal privacy and NFT RPC providers
Audit baseline: v0.9.2 / e317af75434f065458dbcd677f0b1a499704fafd.
Impact
A stalled or oversized response from a third-party data service or RPC endpoint can indefinitely wedge a cached terminal request or consume excessive tab memory. This affects terminal availability; it does not directly expose wallet secrets or bypass approval.
Required remediation
Introduce one reusable bounded terminal network boundary that:
- composes the caller signal with an internal deadline;
- enforces a response-byte cap before JSON parsing, including a
Content-Lengthprecheck where available; - stores only a bounded error-body prefix;
- ensures shared in-flight requests have their own lifecycle even when all callers detach;
- bounds retry and backoff duration;
- supplies a bounded
baseFetchto Starknet RPC providers; - is used by every AVNU, Vesu, privacy, NFT, and market-data path.
Preserve the current rule that semantic RPC failures do not trigger endpoint failover.
Retest criteria
- A request that never produces headers is aborted internally.
- Oversized success and error bodies are rejected before unbounded parsing/storage.
- Caller cancellation does not cancel work still needed by another caller.
- A timed-out shared request is removed from
inFlightand can be retried. - Retry/backoff cannot outlive the total request budget.
- Every production terminal fetch and
RpcProvideris covered by the bounded boundary. -
bun run check,bun run check:coverage, and terminal build pass.
Severity: Low · Area: terminal availability and resource exhaustion · Status: Open
Activity
mossbot55 commentedon Oct 2, 2026
I will check this against the current terminal HTTP/RPC layer (
data/core/client.ts,data/core/cache.ts,protocols/support/provider.ts, and the direct AVNU, Vesu, privacy and NFT fetch/RPC paths) and try to reproduce the resource-bounding gaps locally, then report what I find.mossbot55 commentedon Oct 2, 2026
Reproduced locally against the current terminal network layer (the
release/v0.10.5tree plus unrelated local work, not committed).Observed behaviour:
GETissued throughdata/core/cache.tswhose upstream never produces headers stays pending indefinitely. The caller's signal is removed before the shared fetch, so once every caller detaches the request keeps its slot in the shared in-flight map; a later request for the same URL is de-duplicated onto that stuck promise and also never settles.fetchJsonindata/core/client.tspasses no composed signal.fetchJsonreads and parses an arbitrarily large success body (a 6 MB JSON body parsed normally), andHttpErrorkeeps the full error body (a 6 MB error body was stored verbatim instead of a bounded prefix).Evidence:
apps/terminal/tests/network-boundary.test.ts, run with the terminal's vitest config. Three checks fail on the unchanged tree (missing deadline, oversized success body accepted, unbounded stored error body); the existing check that one caller's abort does not cancel a request another caller still needs passes. I reproduced this at the unit level only; no live upstream was contacted.Limitations: this is a local reproduction of the resource-bounding gaps, not a test against a production endpoint.
derek-flossman commentedon Oct 13, 2026
Fixed in #510, merged into
release/v0.10.6through batch #642 (fecb613).