v1.5.4 #
latestA security release. A box could steer Cleat into reading, writing or moving files on your host outside the cage. Every path we found is closed.
An internal audit followed the v1.5.3 image paste fix through the rest of the code. It found the same shape in many places: Cleat wrote or read a file inside a folder the box can write, so the box could swap that file for a link and send the operation somewhere on your host. Upgrade with cleat update, or brew upgrade cleatdev/tap/cleat for a Homebrew install. Every box made before this release is rebuilt once, the next time you start it with cleat, to move its input history to a folder the box cannot reach. Your sessions, logins, trust and history are kept. End any cleat session that was already open, since a running session keeps the old code until it exits.
Fixes #
- A box could get the host to write or move a file outside the cage - to save a login, a renamed session, a deleted conversation, an edited
.cleator the settings it mirrors into a box, Cleat wrote inside a folder the box can write, then moved the result into place. A box could plant a link at the name Cleat was about to use and send the write to one of your own folders. Every one of these now builds the file in a folder the box cannot see and lands it with a single move that replaces a link instead of following it. - The input history file could be pointed anywhere on your host - each box mounts a per-project history file. Its source sat in a folder the box can write, so a box could replace it with a link and have the next start mount one of your files into the box, writable. The history now lives in a host-only folder. Closing this for an existing box needs a one-time rebuild, which Cleat does for you on the next start.
- Deleted conversations were reachable by the box - the session trash sat inside the folder a box mounts, so a delete could be steered onto the host and a deleted transcript stayed readable by the box for thirty days. The trash moved to a host-only folder. An old trash is carried across the first time you run a session command.
- The browser and clipboard bridges wrote logs and markers the box could redirect - the proxy log, the watcher log and the liveness markers moved out of the box's folder. The readiness signal a box does need to see is now written from inside the box, so a link there stays inside the box. When the private folder cannot be made, the bridge turns off for that session rather than falling back inside the cage.
- A box could make the host follow a link to a slow or endless file - reads of any file a box can write (a
.cleat, an env file, a[setup]script, a session log, a box.claude.json) are now bounded in time and size, so a pipe or a device the box swaps in costs a moment instead of hanging the command. - A capability could be granted from a
.cleatyou did not approve - the trust check now reads the project.cleatonce and grants, prompts and records from that single read, so a file swapped in after approval cannot change what a box gets. An unknown capability name is dropped with a warning instead of counting toward trust. - A project env file could pull host variables into a box without consent - a bare
KEYline in a project.cleat.envasks for a host variable by name. Those names now join the project's trust prompt and are passed only after you approve them. A project that uses them asks once after upgrading, including in CI, whereCLEAT_TRUST_PROJECT=1approves them. AKEY=VALUEline, which carries no host value, is unaffected. A symlinked env file is refused. - Box text could rewrite your terminal - a URL, a
.cleatvalue, a filename or other text the box or the repo controls is stripped of control bytes before Cleat prints it, so it can no longer move your cursor or hide what a report says.
Changes #
- A
--forkcopy now briefly pauses any running box that shares the project, so the copy is taken from a still tree. - 3470 (+215) behavioral tests (a regression for every fix). 1581 (+221) mutations caught, 0 missed, 0 skipped (1582 on a host with inotify-tools).