Report privately through GitHub's private vulnerability reporting. Please do not open a public issue for a vulnerability.
ctx reads data it did not create and cannot vouch for, so the threat model is worth stating plainly:
- Transcripts under
~/.claude/projectsare written by other tools and record whatever an agent read: a repo's README, a fetched page, a tool result. All of it is untrusted input. - Worktree paths come from those transcripts, not from you. ctx runs git in directories it was told about rather than ones you chose.
- Distilled summaries are injected into other agent sessions, including summaries of sibling worktrees, so a poisoned transcript in one worktree has a path toward every sibling agent.
- Repository config that git would execute (
core.fsmonitor,filter.*.clean, and the rest) is enumerated and neutralized before any git command runs. Overrides travel as environment entries rather than-c key=value, because-csplits at the first=and a config subsection name may legally contain one. git older than 2.31 does not support that mechanism and is refused rather than probed unprotected. - git is not allowed to descend into submodules, whose config the superproject's enumeration cannot see.
- Directories owned by another user are never probed.
- Untrusted strings are stripped of control, bidi and zero-width characters, collapsed to a single line, and length-capped before they reach a terminal, a state file, or another agent's context.
- Injected context is wrapped in a delimiter carrying a random per-invocation suffix, so summarized content cannot close the block and continue as instructions.
- The distiller subprocess runs with no tools, no MCP servers from your configuration, and a reduced environment.
- The MCP tools accept any absolute path, so a steered agent can create state entries for directories you never opened. No path traversal is possible; the effect is clutter on the board.
- State files under
~/.ctxare readable by your user's other processes. Do not pointCTX_DIRat a shared location. - Distillation sends a bounded extract of transcript text to Anthropic. It is never the raw transcript, but it is your session content leaving the machine.