The off switch was inside the sandbox
CVE-2026-82533, published September 8, is a 9.4 in DeepSeek Harness: the sandboxed coding agent could switch off its own sandbox with one shell command. The harness ran the agent's commands in an OS sandbox that constrained file writes, and it exposed its control plane as an HTTP interface on loopback, which the sandbox never covered. The check guarding that interface read the Host header the caller supplied and never looked at where the connection came from. In Bromure Agentic Coding the agent is already unconfined inside the VM, and the control plane it would have to call does not exist on its side of the line.
This one took no exploit. The confined agent ran a shell command against a local port, asked the sandbox holding it to switch itself off, and the sandbox agreed.
DeepSeek Harness runs a coding agent's commands inside an operating-system sandbox. The sandbox is narrow and deliberate: file writes stay inside the workspace and the temporary folders, and everything else the agent does is someone else's problem. The project's own command-line reference says as much. Under default settings, "reads and network access are not confined."
The harness also has a web interface. It runs on the same machine, on a local
HTTP port, and the harness hands its address to the agent's shell so tools can
talk to it. That interface is the control plane: it holds a session's mode,
including the mode called danger-full-access, which turns off the sandbox and
stops the approval prompts.
Both of those designs are ordinary. Put them next to each other and the agent can switch off its own sandbox with one command, because the sandbox never covered loopback and the control plane never checked who was calling.
Researchers at OX found it. VulnCheck published it on September 8 as CVE-2026-82533, CVSS 9.4. It worked on a default install, with no network exposure and no credentials, until DeepSeek shipped a fix on August 27.
The check that read the envelope
The interface had no authentication at all. What stood in for it was a function
named isTrustedApiRequest, and
DevOps.com quotes what it did:
it "read the 'Host' request header and allowed access if the value was a loopback
authority or appeared in a configured 'trustedHosts' list."
The Host header is a line of text the client writes. It says what address the
client believes it is talking to, and a caller anywhere on the network can type
localhost into it. The connection's real origin sits a layer down, in the TCP
peer address, and DeepSeek's check never read that value. The CVE record files
the bug under CWE-345,
Reliance on Untrusted Inputs in a Security Decision.
The agent, sitting inside a sandbox that permitted network calls, made one to the
interface and set its own session to danger-full-access with approval set to
never. As The Hacker News put it,
the mode change "did not require explicit approval because it modified session
settings rather than requesting new permissions."
The approval system worked as designed. The agent never asked to do something dangerous; it asked to change a setting, and that setting governed whether dangerous things get asked about at all. A permission gate inspects the operation in front of it. This request was a configuration write, and configuration writes were not on its list.
The same door, facing the other way
An interface that trusts a header the caller supplies does not care which
direction the connection arrives from. If the port was reachable over a network,
the same call worked from off the machine: an unauthenticated stranger could take
control of the agent and export every stored conversation, with no API key and
without spending a token on a model call. That is why the CVSS 4.0 vector opens
with AV:N, and why the number is 9.4 rather than something local and mild.
The timeline has a detail worth keeping. Two developers posted the finding on DeepSeek's GitHub discussion board on August 13 and 14, on their own, before OX confirmed it on August 24 and before a CVE existed. The repository had more than 216,000 stars on September 9 and no security policy file describing how to report a vulnerability in private, so the only place left to put it was a public thread. The fix, when it came, was authentication: the tool now prints a one-time token at its startup address, the browser exchanges that token for a signed cookie, and every call to the interface requires the cookie.
If you run this harness, check the version on your machine rather than the version
the project ships. Third-party desktop wrappers bundle their own copy.
0.1.2-alpha.1 was GitHub-only on August 27, 0.1.2-alpha.2 on August 30 was the
first npm release carrying the fix, and one Windows wrapper sat on 0.1.1-rc.2
until it moved to a patched build on September 6.
Your harness has one of these too
You could file this under one project's bug and move on. The shape travels, because agent harnesses are sprouting local control planes: a status server for the dashboard, an IDE bridge, an MCP endpoint, a page on localhost that renders the diff. Each is a small HTTP service on your machine, and the code your agent runs can reach all of them, because the agent runs on that machine and localhost is what "that machine" means.
Once a control plane sits next to the thing it controls, one question governs the outcome: can the confined party address the confinement's settings? DeepSeek answered yes, through a check that took the caller's word for it. A stronger check still answers a question that should never have been askable. An authentication function is code, code has fallback branches, and this year has been a long parade of security decisions failing in the branch no one exercised.
Where the switch lives in a Bromure workspace
Bromure Agentic Coding starts from the other end. A Bromure workspace leaves the agent unconfined.
Inside the guest the agent already has what DeepSeek Harness would call
danger-full-access. That is the resting state, by design. The manual says as much: a prompt-injected or
otherwise misbehaving agent "can do anything it likes inside the guest, but it
cannot read a real API key, sign with a real AWS secret, or extract an SSH private
key — none of those exist on its side of the line." The agent can write anywhere
in the filesystem, run what it wants and bind any port it likes, so it has no mode
left to escalate to. The boundary is a hypervisor edge with the agent on the far
side of it.
The guest therefore has no address for the control plane at all. The workspace's
policy (guardrails, credentials, firewall rules, MCP servers) lives in a
profile.json under ~/Library/Application Support/BromureAC/profiles/ on your
Mac, and you change it in the Edit workspace window. The guest has no filesystem
path to that file and no network route to the process that reads it.
The two sides talk over virtio sockets, point-to-point host-to-guest bridges that
run outside the VM's network. A workspace VM has eight, each with a job:
8443 carries the guest's HTTPS to the host proxy, 8444 is the ssh-agent bridge,
8445 feeds the AWS credential helper, 5800 is the terminal and file path, 5010
relays OAuth callbacks. Each one serves a fixed protocol and none of them takes a
Host header, so a caller has no trustedHosts list to talk its way into.
Identity on a vsock is topology: which bridge the bytes arrived on. You cannot
type that into a request.
Approvals that cannot be set to never
The second half of danger-full-access turned off the prompts, and that half
deserves its own answer. An agent that silences its own approvals is the part
that would keep me up.
In a Bromure workspace the prompts live on the host. The proxy raises them after
the request has already left the VM, so the session inside the guest carries no
setting that could suppress one. Ask before use pauses the first use of a
credential in a session and offers time-bounded grants: five minutes, an hour, the
rest of the session, or Don't allow. A write policy set to Prompt before
write stops each mutation with a dialog headed Allow write on "<scope>" from workspace "<name>"? showing the literal operation, the SQL statement itself or
METHOD /path for a REST call. Allow once creates no grant at all, so the
next write prompts again. Grants live in memory and vanish when the session window
closes.
The guardrails page states the property in one clause: a write policy is "enforced
in the proxy, so a compromised agent in the VM can't bypass it." The egress
firewall underneath it works the same way, an ordered rule table with an
Unmatched traffic control you can set to Deny, applied twice: once at the
virtual switch by destination IP and DNS-snooped hostname, once at the proxy by
TLS server name and, for web rules, by HTTP method. Rule edits reach running
sessions without a reboot.
An unattended run fails the safe way. A workspace driven headless over SSH or an
automation gets the same four choices as a text prompt inside its tmux, and no
answer means deny. The worst outcome there is a blocked call and a red row in the
Security Timeline. In this CVE, the agent set approvals to never and the prompts
went away.
If you run an agent harness on your Mac
Ask what its local interfaces are and who can call them. Inside a Bromure
workspace, bromure-cli vm ports <workspace> prints the guest's live
listening sockets, with port, protocol, address and process, and loopback-only
binds marked. The VM dashboard's Listening Ports card shows the same. That
inventory is the question this CVE turned on, and one command answers it.
If the interface faces outward too
The remote half of CVE-2026-82533 needed the port to be reachable. Workspace VMs run on a private NAT network: they are reachable from your Mac, but they are "not exposed on your physical LAN, and inbound connections from elsewhere are not possible unless you explicitly publish a service." An unauthenticated agent-control port that a coffee-shop network cannot route to leaves you a patch to apply on your own schedule.
Confinement you can revoke is a preference
DeepSeek shipped a weak check and fixed it three days after OX confirmed it. The lasting part is what the check was guarding. A boundary drawn around a process by that process's own runtime is a boundary the process can negotiate with: it has an address, an API, and a settings object with a field in it. Somewhere behind that field runs a code path deciding whether this caller may write it, and a code path of that kind is one bad default away from decoration.
Draw the boundary under the process and there is no counterparty to negotiate with. The agent in a Bromure workspace holds root, holds the whole filesystem and can start any service it likes on any port. Its API keys are decoys, its only route to the network is a virtio socket to a proxy on your Mac, and the file holding its permissions sits somewhere it cannot read. Hand the agent everything on its side of the line and you stop having to defend the line.
Coding agents will keep growing local control planes, because a control plane is how you build a dashboard, an IDE bridge or a diff viewer. Each project then has to answer whether the code its agent runs sits on the same side of the line as the settings governing that agent. Get that wrong and authentication is the only thing still holding, which is how a 9.4 comes down to one shell command. Install Bromure Agentic Coding and put the switch somewhere your agent cannot reach it.