You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
All WebSocket methods that accept a cwd field pass it directly to service-layer
operations without validating it against registered project workspace roots. A
WebSocket client (authenticated or not, depending on config) can send an arbitrary
absolute path as cwd and perform filesystem writes, directory listings, git
operations, or shell spawns in any directory the server process has access to.
resolveWorkspaceWritePath in apps/server/src/wsServer.ts (line 155) validates
that relativePath does not escape the supplied workspaceRoot via ../ traversal,
but trusts workspaceRoot itself completely. The ProjectWriteFileInput schema in packages/contracts/src/project.ts only requires cwd to be a non-empty trimmed
string.
No server-side middleware or guard constrains client-supplied cwd to a known project
workspace root (ServerConfig.cwd or orchestration state).
Reproduction
Start the T3 Code server (no --auth-token):
bun run --cwd apps/server start
Connect a WebSocket client to ws://localhost:3773.
Observe /tmp/proof.txt is created with the supplied contents.
The same pattern works with projects.searchEntries (to list /etc, ~/.ssh,
etc.) and terminal.open (to spawn a shell in any directory).
Impact
Local attack: Any process or browser extension that can open a WebSocket to localhost:3773 gets full filesystem access scoped to the server's OS user.
Network attack: In default web mode, the server binds to all interfaces without
requiring an auth token. Any device on the same network can exploit this.
Suggested fix
Add a server-side guard that validates every client-supplied cwd against the set of
known project workspace roots from the orchestration read model (or against ServerConfig.cwd). Reject requests where cwd does not match a registered project.
// Example guard (pseudocode)functionassertKnownWorkspaceRoot(cwd: string,knownRoots: Set<string>): void{if(!knownRoots.has(cwd)){thrownewRouteRequestError({message: "cwd does not match any registered project workspace.",});}}
Apply this to every route handler that accepts a cwd parameter.
Activity