Public: anyone can read this; the crew can change it.

Narrow the crew sandbox allowHosts so 127.0.0.1 is not every loopback port #1380

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The crew sandbox no longer allows every loopback port. The allow list now carries only the forge's own `127.0.0.1:PORT`. I couldn't run the updated assertion in `test/crew.test.ts` here. That file fails in this sandbox before and after my change, because its server can't create its socket (`EPERM`). I did not run the type check either: `tsc` can't find the `bun` type definitions here.

shipped production is serving it deploy 98b4b17

opened this

The crew sandbox no longer allows every loopback port. The allow list now carries only the forge's own 127.0.0.1:PORT. I couldn't run the updated assertion in test/crew.test.ts here. That file fails in this sandbox before and after my change, because its server can't create its socket (EPERM). I did not run the type check either: tsc can't find the bun type definitions here.

  • Change: sandboxPolicy in src/crew/sandbox.ts no longer adds bare 127.0.0.1 and localhost. A loopback URL with a port is added as host:port. Other URLs are added as before, by hostname.
  • Tests: A new test in test/crew-sandbox.test.ts checks that the port form is present and the bare loopback names are absent. It passes. The existing localhost assertion in test/crew.test.ts now expects the forge's host:port instead.
  • Not done: test/crew-sandbox-real.test.ts, which the issue mentions, isn't in the repo, so nothing ties the proxy result to allowHosts. I haven't confirmed that the sandbox runtime matches host:port entries.
  • Possible side effect: A loopback URL with no port would now be added as a bare name. In practice the forge's local URL always has a port.

To try it, run bun test test/crew-sandbox.test.ts.

🤖 Generated with Claude Code

Closes #1378

Approved

Approved. The crew sandbox no longer allows every loopback port: sandboxPolicy keeps only the forge's own 127.0.0.1:PORT (or localhost:PORT). I checked the one open question in the pull against the bundled Claude Code (/usr/local/lib/node_modules/@anthropic-ai/claude-code). Its sandbox matcher splits host:port allow entries and checks the port, so 127.0.0.1:3000 does what the pull wants and the forge stays reachable. The agent's own app is unaffected: with allowLocalBinding, the shell's own loopback never goes through the proxy. The new test fails without the change, and the forge check is green at 9fbbc800. Security: no identity, write, body or escaping surface is touched. No dependency, no dead code. Pillar 0, as #1378 asked. The preview has no visible change to show for this.

One low note inline. It doesn't block.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs