basecamp / basecamp/hotcell

A nonempty output descriptor lets stale bytes pass as this request's output

Open
#32 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Ruby
Stars
23
Forks
0
Avg merge
11h 43m
Merged PRs (30d)
27

Description

Bytes a request never produced can be reported as that request's successful output. `descriptors.rb` validates that an output is a regular file, one-way, and not `O_APPEND`, but never checks its initial size or offset. A direct output then reports the file's total final size rather than what this request wrote, and a staged copy writes without truncating the caller's file first (`Output#post`). Both the worker and the client reject only a measured final size of zero.

Reproduced through the server harness and through the documented `HotCell::Client#perform_in_hotcell` API, against a caller file already containing `SECRET-TAIL`:

```
silent operation -> success, "SECRET-TAIL"
one-byte write -> success, "XECRET-TAIL"
```

The cell cannot read those bytes, so one-way access still holds. The defect is attribution: an old sensitive tail can be published or attached as fresh output, and content can be smuggled or corrupted under a success verdict.

The shipped Active Storage integration is unaffected — it opens fresh, truncated tempfiles. This reaches custom clients, and our custom-client documentation does not state the invariant.

## Fix direction

Reject, on both client and server, any output whose initial size or current offset is nonzero. Reject rather than truncate: silently destroying caller data is the worse failure. Measure bytes produced by the request rather than the file's total size.

Acceptance: reject nonempty and nonzero-offset outputs before the operation runs; test every member of a multi-output call; a one-byte write leaves exactly one byte; a silent operation stays a transient failure.

`HC-PT-006` of the purple-team assessment of 2026-08-22, rated Medium for custom clients.

Contributor guide

Open the contributing guide

Research direction

Start with descriptors.rb and Output#post, then trace the corresponding client and server output handling through the server harness and documented HotCell::Client#perform_in_hotcell API. Verify behavior for every output in a multi-output call: nonempty or nonzero-offset files are rejected before execution, a one-byte write leaves exactly one byte, and a silent operation is a transient failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.