mirror of
https://github.com/coder/coder.git
synced 2026-06-05 22:18:20 +00:00
5576dc86b7
Six concrete fixes from @ibetitsmike's review on PR #25983: P1 symlink arbitrary read: the resolver previously called os.ReadFile on any AGENTS.md/.mcp.json/SKILL.md it walked into, including symlinks, so a workspace with `nested/AGENTS.md -> ~/.ssh/id_rsa` would have shipped the target. Symlinks are still followed (codex follows them too, and they are the standard way to compose monorepo agent docs), but the resolved target must now stay inside the contributing scan root or the resource is emitted as StatusInvalid. Broken symlinks and non-regular targets are emitted as StatusUnreadable. P1 .mcp.json secret exfiltration: readMCPConfig used to ship the raw file bytes, which embed Env tokens and Authorization headers. The resolver now produces metadata only (path, SizeBytes, ContentHash). Change detection still works; the live tool list flows through MCPProvider as a KindMCPServer resource, which is what consumers actually need. P2 v2.10 contract ahead of behavior: revert tailnet/proto.CurrentMinor to 9, switch the agent's connect site back to ConnectRPC29WithRole, and disable the PushContextState push goroutine. The DRPCAgentClient210 interface, the agentcontext.Manager, and the push code paths remain compiled and tested so the v2.10 bump in the follow-up that adds coderd persistence is a small, focused change. A TestAgent_ContextStatePushed skip and a comment at the connect site call out the re-enable steps. P2 boot-time env sources lost: relative CODER_AGENT_EXP_*_DIRS paths used to be dropped during agent.init when the manifest's working directory was still unknown. Add Manager.SeedSources, a trusted late-binding equivalent of InitialSources that bypasses AllowedRoots, and call it from handleManifest with the now-resolved working directory before Trigger. P2 degraded watcher re-arm loop: when fsnotify init fails, Sync used to schedule its OnChange callback, the Manager's signal handler turned it into another Sync, and the cycle repeated every 250ms forever. Degraded Sync is now a true no-op; manual Resync, AddSource, and RemoveSource still drive re-resolves. P2 stale-epoch Resync mutating the watcher: a Resync pass that loses the epoch race already skipped publishing its stale snapshot, but still called watcher.Sync with stale roots. That removed watches on sources only the winning pass knew about. The stale branch now returns the published snapshot without touching the watcher. P2 MCP byte cap not enforced: applyMCPCaps previously only checked the resource-count cap, so a provider returning one big KindMCPServer payload could exceed MaxSnapshotBytes with StatusOK. The cap helper now picks up where applyCaps left off and stamps StatusExcluded plus a snapshot error on MCP entries that breach the count or byte budget. Adds regression tests for symlink-inside, symlink-outside, broken symlinks, MCP secret omission, MCP byte cap, and the manifest-late SeedSources path.