# Knowns Unrestricted Path Traversal leading to out-of-bounds arbitrary .md file read, write, and deletion in MCP Docs + Memory Tools

Knowns MCP docs/memory tools join user paths with filepath.Join without containment checks, enabling arbitrary .md read/write/delete outside the project sandbox.

- Payout: Research
- Severity: high
- Program: Knowns
- Found by: uziii2208, hoanggxyuuki
- Disclosed: 2026-09-25
- CVE: CVE-2026-86439
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-9gfj-28hw-jchp
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-9gfj-28hw-jchp
- Tags: area:ai domain:ai impact:data-leak impact:integrity kind:research platform:ghsa sev:high tech:go technique:chained technique:source-review vuln:access-control vuln:path-traversal

**Target:** MCP docs and memory tools (Go storage layer)
**Root cause:** DocStore and MemoryStore concatenate user-controlled path/id with filepath.Join() and never verify the resolved path stays within the base directory, so ../ escapes the sandbox. Additionally docs.update with newPath performs a delete via Rename() but is registered as CapWrite, not CapDelete.
**Steps:**
1. Call `docs.get` with `path="../../../victim/secret"` to read a file outside the project root via DocStore.Get().
2. Call `docs.create` with `folder="../../../victim"` to write a file outside the project root via DocStore.Create().
3. Call `docs.update` with `path="../outside/secret.md"` and `newPath="../../../victim/renamed.md"` to delete the file at path via Rename()'s os.Remove, bypassing CapDelete since docs.update is CapWrite.
4. Call `memory.update` with `id="x/../../../../victim/secret"` to read/overwrite a file outside the project root via MemoryStore.Update().
**How found:** Code review of the storage layer: noticed filepath.Join() used on user-controlled path/id with no post-join prefix containment check, and that Rename() calls os.Remove on the old path while docs.update is only classified CapWrite.
**Exploitation:** An attacker with MCP tool access (zero-credential when the server runs without a password due to a separate auth bypass) sends traversal paths to docs/memory tools to read, write, or delete arbitrary .md files outside the project sandbox; the rename-as-delete path also defeats read-write-no-delete presets.
**Escalation:** Chains with the previously identified auth bypass so all MCP tools are reachable without credentials, turning it into a zero-credential arbitrary file operation.
**Insight:** When auditing MCP/file-backed tools, grep for filepath.Join(base, userInput) and check for a post-join HasPrefix containment check; also audit permission registries for operations that delete (rename, move, overwrite) but are classified as write-only, since they bypass delete restrictions.

