Back to blog
Engineering

The Agent Turned Off Its Own Sandbox

A confined agent in DeepSeek Harness could call its own local control API and switch its session to full access. Isolation the agent can reach is isolation the agent can undo.

A concrete courtyard enclosed by a tall pink wall, a wooden bench at its foot and a band of late sunlight crossing the floor from an opening in the wall.

On August 13, the day DeepSeek open-sourced its agent runtime, someone posted a report with test output: a process still held by the sandbox had reached the tool's local web interface and switched its own session to danger-full-access. The next day a second report listed the requests that interface accepted without any credentials (The Hacker News, September 9, 2026). On September 8 the flaw was published as CVE-2026-82533, scored 9.4 out of 10 by VulnCheck (OX Security, September 8, 2026).

The bug is one header check. The lesson is where that check lived. A sandbox whose control plane runs on the same machine as the agent, within the agent's reach, is a suggestion. DeepSeek Harness confined the agent's file writes and left the switch that loosens the confinement one HTTP request away. Isolation the agent can reach is isolation the agent can undo.

What DeepSeek got right

Credit first, because the design has a lot to admire. Harness went public on August 13 under the MIT license. Every session is an append-only JSONL stream, and the system refuses to run unconfined: when no sandbox backend is available it raises SANDBOX_UNAVAILABLE instead of falling back. On Linux it prefers bubblewrap with Landlock as the fallback, and it offers three modes: read-only, workspace-write, and danger-full-access, which turns off confinement and approval prompts entirely (ComputingForGeeks, August 20, 2026). On macOS the backend is Seatbelt (OX Security, September 8, 2026).

The append-only log is the part I would copy. A log that only grows means every session can be explained after the fact. I argued in Every Agent Demo Hides the Same Number that independent review is what production adds and demos skip; review needs an ordered record of what happened, and Harness writes one for every session by default. The repository had more than 216,000 stars on September 9, a count of bookmarks rather than installs (The Hacker News, September 9, 2026), so this design has a great deal of attention.

None of that care reached the one place it mattered most.

One request

The web interface listens on 127.0.0.1:3080. Under the default workspace-write mode, writes stay inside the workspace and temporary folders, while "reads and network access are not confined" (The Hacker News). Loopback is network. So the agent, sandboxed exactly as designed, could talk to the interface that configures its sandbox.

What DeepSeek Harness's default sandbox confinedThree rows. File writes are confined to the workspace. File reads are not confined. Network access, loopback included, is not confined, and that row is gold because the control API on 127.0.0.1 port 3080 sits inside it.What workspace-write confinedFile writesconfined to the workspaceFile readsnot confinedNetwork, loopback includednot confinedThe control API listens on 127.0.0.1:3080, in the gold row.Sources: The Hacker News, Sept 9, 2026; ComputingForGeeks, Aug 20, 2026
The default mode confined what the agent could write. The switch that loosens the sandbox sat behind the row it left open.

The interface decided whom to trust by reading the request's Host header. A comment in that file says the check "is not an auth layer" (The Hacker News). The comment was accurate. In OX Security's test the agent needed a single curl command from inside the sandbox: it called the harness's own unauthenticated API and raised its session to danger-full-access with approval set to never (OX Security, September 8, 2026). Every command after that ran unconfined and without prompting. The client writes the Host header, so the check asked the caller to vouch for itself.

OX attributes the flaw to trusting that header instead of the connection's real source address. That diagnosis is correct, and it also shows how narrow the margin was. On a default local install the agent runs on the same machine as the interface, so its connection comes from 127.0.0.1 as well. As far as I can tell from both write-ups, a source-address check would keep out a remote caller and still could not tell the agent apart from the person who started it.

The fix, and what it rests on

The fix landed on GitHub in 0.1.2-alpha.1 on August 27, and 0.1.2-alpha.2 on August 30 was the first npm release to carry it (The Hacker News). The tool now prints a one-time token at startup; the browser exchanges it for a signed cookie, and every call to the interface requires that cookie.

CVE-2026-82533 timeline, August 13 to September 9, 2026Seven dated events. A gold band runs from August 13, when the escape was first reported publicly, to August 30, when the first fixed release reached npm: 17 days.17 days from report to npm fixAug 13Harness goes public under MIT. Same day,a report shows the sandbox escape.Aug 14A second report lists requests theinterface accepts with no credentials.Aug 24OX Security reports it to VulnCheck.Aug 27The fix lands on GitHub, 0.1.2-alpha.1.Aug 300.1.2-alpha.2, the first fixed npm release.Sep 8CVE-2026-82533 published, CVSS 9.4.Sep 9More than 216,000 stars on GitHub.Sources: The Hacker News, Sept 9, 2026; OX Security, Sept 8, 2026
Gold marks the 17 days between the first public report and a fixed release on npm.

It is the right fix for the bug, and it moves the boundary from a header to a secret. The agent's confinement now holds as long as the agent never reads that token or that cookie. Under workspace-write the agent can read what the user can read, so the question becomes where the token and the cookie end up: terminal scrollback, a log file, a browser profile on the same disk. I have not seen anyone test this, and the fix may well hold. The kind of fix is the point: a secret kept on the same machine as the process it is kept from.

Where the switch lives

Draw the two arrangements side by side and the difference is plain.

Where the switch lives: same machine versus outside the guestTop: on one machine, the agent sits inside a sandbox and a gold arrow runs from it to the control API on 127.0.0.1 port 3080, setting full access with one request. Bottom: the agent's whole guest machine is the sandbox, and a control plane outside the guest admits the run, sets its limits and keeps the record, with control flowing into the sandbox.Where the switch livesSame machinesandboxagentcontrol API127.0.0.1:3080one requestfull accessWrites confined; reads and network open, loopback included.Outside the guestthe whole guest isthe sandboxagentmay change anything herecontrol planeadmits the run,sets its limits,keeps the recordNothing inside the sandbox sets what the sandbox allows.
Top: DeepSeek Harness on a default local install. Bottom: the agent's whole guest machine is the sandbox, and its limits are set from outside it.

In the top arrangement, the agent, its sandbox and the control API share a machine, a user account and a network stack. The sandbox is a policy that the control API enforces, and the control API takes requests. Every path from the agent to that API is a way to rewrite the policy: a loopback port, a socket file, a config file the tool re-reads on change. Each one has to be found and closed, in every release, before anyone else finds it. DeepSeek closed the one that was reported. The shape that produced it is still there.

In the bottom arrangement, the agent's whole guest machine is the sandbox, and the thing that decides its limits runs somewhere else. The agent can change anything on its own machine, and the worst it can do is damage a box that gets thrown away when the run ends. None of its moves touch the switch, because the switch lives outside the guest.

This is old knowledge. A virtual machine's guest does not get to configure its hypervisor. Agent tooling keeps relearning it because the first agent tools ran on the developer's own laptop, where the agent, the tool that supervises it and the person all share one account, and convenience put the control panel next to the thing it controls.

What we are building instead

At Rush each run works in a cloud sandbox with a browser, and we are rolling out one microVM per task: a guest with its own writable disk. The API that admits the request and the service that starts and drives the microVM run outside that guest, and that is where the run's limits come from. A run that has moved has its guest to itself; runs not yet moved still share pods with other runs. The trajectory of what the agent did is captured as the run happens, and the result has to come back with proof: a PR with checks for code, or a report, files or an answer. A run that is missing its proof ends as needs_review. When you run more than a handful of agents, that record is how you find out what any one of them did.

Honest limits. A guest boundary is stronger than a policy inside a shared account, and it still leaves work. The host that runs the microVMs is trusted infrastructure shared by many runs, so it has to be patched and hardened, its runtime sockets kept private, and what each guest can reach on the network is a policy of its own. Proving that isolation fails closed between customers under concurrent load is work we have not finished. That last one is the question DeepSeek's interface failed, asked one level up, and we treat it as something to prove on each release.

The test for any agent sandbox is what the agent can talk to, from inside, that can change the rules. When the answer includes a control interface inside the agent's own trust boundary that asks for no credential the agent cannot read, the rules hold only until the agent finds it, and an agent that reads and runs commands all day will find it.

Read Next