Repository navigation
fix(sandbox): require a per-sandbox secret on the egress broker - #220
Merged
Merged
Conversation
quickbeard
force-pushed
the
fix/broker-require-token
branch
from
August 13, 2026 07:34
15757c4 to
3d87144
Compare
Found reviewing the sandbox surface: the WSL backend must bind the
broker on TCP for the guest to reach the host across NAT, and the broker
had no authentication. Anything else able to reach that port — any local
process, and whatever the firewall lets onto the LAN — could use it as
an open proxy to the model gateway, spending the real token the broker
attaches host-side. The unix-socket backends were narrower but equally
unauthenticated.
createBrokerServer now takes an optional shared secret, checked before
the route table is consulted so an unauthorized caller cannot even probe
which upstreams exist, and the desktop generates a fresh one per sandbox
start and injects it as the guest provider's apiKey.
Verified against a running sandbox: an unauthenticated request gets
{"error":"sandbox egress unauthorized"}, while the guest's injected
token is accepted and forwarded upstream with the real credential
swapped in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
quickbeard
force-pushed
the
fix/broker-require-token
branch
from
August 13, 2026 07:40
3d87144 to
9eb6a77
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Result of a security review of the sandbox surface. One finding worth fixing before this ships to a fleet; the rest of the review is summarized below.
Finding: the broker was an unauthenticated proxy to the gateway
The WSL backend cannot use a unix socket — the guest reaches the host across NAT — so its broker binds TCP
0.0.0.0. It had no authentication, and the broker attaches the real gateway credential host-side. So any other process that could reach that port (any local process on the Windows host, plus whatever the firewall admits from the LAN) could spend the corporate gateway token at will, with nothing tying the usage back to a sandbox. The vz/bwrap unix sockets were narrower — same-user local processes only — but equally unauthenticated.Fix
createBrokerServertakes an optional shared secret. It is checked before the route table is consulted, so an unauthorized caller cannot probe which upstreams exist (a wrong token gets 401 on/not-a-route, not 403).apiKey— replacing the previous fixed"sandbox-broker"placeholder. The real gateway token still never enters the guest.Consequence for named egress rules (#212): tools using those routes must send the token too. It is readable inside the guest at
/codev-config/codev.json.Verification (against a running sandbox, over its unix socket)
Suites: sandbox 93 pass / 2 skip, desktop 76 pass.
Rest of the review (no changes needed)
new URL()normalization defeats..and%2e%2e(both resolve away from the prefix and get denied), and the upstream host comes from the route table, never from the request — an absolute-form request line cannot redirect the forward.boot.jsonholds the sandbox's server password inside the app data dir (protected by the user's home permissions).🤖 Generated with Claude Code