GHSA-j4r7-8ph4-43g3: Path Traversal
Summary faf-mcp MCP tools accept a caller-controlled path argument and resolve it (~ expansion + path.resolve()) straight into a filesystem read/write without confining it to a trusted project directory. An absolute path or ../ traversal is resolved and used as-is, so the server process can be made to read — and, via the file tools, write — files outside the intended .faf project context. The only remaining limit is OS file permissions.
Affected tools The shared getProjectPath() chokepoint (feeding the .faf tools) and the general-purpose fafread / fafwrite file tools resolved a caller path straight into a read/write with no confinement (denylist-only); an absolute path still reached home-directory secrets, and fafwrite could write outside the project.
Impact An MCP client — or an LLM prompt-injected via attacker-controlled content (a web page, README, ticket, or .faf) into issuing a tool call — can read any file the server process can read: SSH keys (~/.ssh/idrsa), cloud credentials (~/.aws/credentials), .env files, source, /etc/passwd; and fafwrite could write outside the project. This is a sensitive-information-disclosure (CWE-200) primitive that far exceeds the declared .faf project-context scope. The server runs over stdio, so the read/write is reached by a crafted tool call (e.g. a prompt-injected agent processing attacker-controlled content).
Patches Fixed in 2.1.3 by confining every caller-supplied path before any filesystem access (safe-path.ts): - Reads are restricted to .faf / .fafm context files, so non-context files (secrets) are refused regardless of directory. - General file ops (fafread / fafwrite) are confined to the project root (cwd + system temp; override with FAFALLOWEDROOTS). - Paths are canonicalized through symlinks (closing the symlink bypass); absolute paths and ../ escapes are rejected; callTool() gains a central PATH-DENIED guard.
Upgrade: npm install -g faf-mcp@2.1.3 (or npx faf-mcp).
Workarounds If you cannot upgrade immediately, run the server only against trusted local projects, and set FAFALLOWEDROOTS (patched versions) to a single project directory for a hard directory boundary.
Credits Identified by the maintainers during a sibling-server audit prompted by the coordinated disclosure of the same class of issue in grok-faf-mcp by Zhihao Zhang (Worcester Polytechnic Institute).
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/faf-mcpto a version that resolves this vulnerability.Fixed in 2.1.3 - Upgrade
Upgrade
faf-mcpto a version that resolves this vulnerability.Fixed in 2.1.3 - Compensating control
If you cannot upgrade immediately, run the server only against trusted local projects and set FAF_ALLOWED_ROOTS to a single project directory to enforce a hard directory boundary.
Event History
Frequently Asked Questions
Who can exploit this issue?
Any MCP client able to invoke the affected tools can supply a path outside the intended project. An LLM may also be induced to make such a tool call through prompt-injected attacker-controlled content, such as a web page, README, ticket, or .faf file.
What access does an attacker need to read or modify files?
No authentication, user interaction, or special path requirements are described beyond the ability to cause an affected MCP tool call with a caller-controlled path. Access is limited by the operating-system permissions of the faf-mcp server process.
Are absolute paths and directory traversal both affected?
Yes. Absolute paths and paths using ../ traversal were resolved and used without confinement to a trusted .faf project directory; home-directory secrets could therefore be reached. The faf_write tool could also write outside the project.
What version contains the fix?
The provided references include the v2.1.3 release tag, but the data does not explicitly state affected or fixed version ranges.