Security: index_codebase path is unbounded, allows arbitrary host file read via search_code (MCP tool)
Summary
ensureAbsolutePath() (packages/mcp/src/utils.ts:15-24) is just path.resolve() — it does no confinement/allowlist check against a project or workspace root. This lets the index_codebase MCP tool index any directory on the host filesystem (sibling repos, ~/.ssh, ~/.aws, ~/.kube, ~/.config, etc.). The customExtensions parameter also additively widens the default file-extension allowlist, so files like .pem/.key/.yaml/.json can be included even though they aren't indexed by default.
Once a directory is indexed (stored in the configured vector DB), search_code returns raw file content (up to 5000 chars) plus the file's path verbatim in the tool response. So a two-call sequence exfiltrates arbitrary host file content through normal MCP tool output:
index_codebasewithpathpointed outside the intended project (e.g.~/.ssh,~/.aws, or a sibling repo the current session shouldn't have access to)search_codewith a query matching known content (e.g."BEGIN PRIVATE KEY","aws_secret_access_key") against that same path
This is a plain local-misuse risk on its own, but it's also the classic MCP "lethal trifecta" amplifier: if an agent using this MCP server ever processes untrusted content (a webpage, an email, a file) containing a prompt injection, that injection can instruct the agent to make exactly these two tool calls — turning this into a remote data-exfiltration primitive, not just a local misconfiguration.
Prior attempt
PR #328 ("refactor: enhance path resolution safety...") touches this exact function but doesn't close the gap — it adds a denylist of 5 hardcoded prefixes (/etc, /var/private, /root, C:\Windows, C:\Users\Administrator). That's trivially bypassed: ~/.ssh, ~/.aws, ~/.kube, ~/.config, any sibling repo, /home/*, /mnt/*, etc. all sail through unaffected. It's also framed as a refactor rather than a security fix, so it may not have gotten security-conscious review.
Suggested fix
Replace the denylist approach with an allowlist/confinement check: resolve the requested path with fs.realpathSync, resolve the intended project/workspace root the same way, and reject any path that doesn't sit under that root (or under an explicit, user-configured list of allowed roots) — rather than trying to enumerate forbidden paths.
Disclosure note
No SECURITY.md exists in this repo and private vulnerability reporting isn't enabled, so filing this as a normal public issue. The vulnerable function is ~10 lines and already fully public in master, and PR #328's own diff (also public) already shows the same line and an inadequate attempt at fixing it, so nothing here goes beyond what's already derivable from the public repo.
Source: zilliztech/claude-context