T09 · Insecure Skill Coding Practices
- Location
references/python_mcp_server.md:532- Finding
Path Traversal in Document Resource Example
- Content
View full analysis
Vulnerability Details
File Location:
references/python_mcp_server.md, lines 532–542
Vulnerability Type: Path traversal leading to arbitrary local file disclosure
Risk Level: MediumVulnerable Code
python @mcp.resource("file://documents/{name}") async def get_document(name: str) -> str: '''Expose documents as MCP resources. Resources are useful for static or semi-static data that doesn't require complex parameters. They use URI templates for flexible access. ''' document_path = f"./docs/{name}" with open(document_path, "r") as f: return f.read()Technical Analysis
The resource parameter
nameis controlled by the MCP client and is directly interpolated into a filesystem path. The implementation does not reject absolute paths or..traversal components, canonicalize the resulting path, or verify that it remains under the intended./docsdirectory.If an MCP server is generated using this documented implementation, an untrusted client can supply a value such as
../../.env. The resulting path escapes the document root and is passed toopen(). This crosses the trust boundary between a remote or otherwise untrusted MCP client and the server's local filesystem.The issue is an insecure instructional coding pattern rather than evidence of intentional malicious behavior.
Attack Path
- A developer uses the documented resource implementation in an MCP server.
- The server exposes
file://documents/{name}to an untrusted MCP client. - The attacker requests a crafted resource name containing traversal components, such as
../../.env. - The server constructs
./docs/../../.envwithout validation. open()resolves the traversal and reads the target if the server process has permission.- The file contents are returned through the MCP resource response.
Impact Assessment
An attacker can read files available to the MCP server process outside the intended document directory. De ...[truncated 379 chars]
- Remediation
View remediation
Remediation Suggestions
- Resolve requested files against a fixed canonical document root.
- Reject absolute paths, traversal components, null bytes, and malformed names.
- Verify after resolution that the candidate remains beneath the canonical document root.
- Account for symbolic-link escapes or disallow symlinks where appropriate.
- Prefer opaque document identifiers mapped to an allowlist of known files rather than accepting filesystem paths.
- Apply equivalent validation in every generated resource implementation.
Example hardening pattern:
python from pathlib import Path DOCUMENT_ROOT = Path("./docs").resolve() @mcp.resource("file://documents/{name}") async def get_document(name: str) -> str: candidate = (DOCUMENT_ROOT / name).resolve() if candidate == DOCUMENT_ROOT or DOCUMENT_ROOT not in candidate.parents: raise ValueError("Invalid document path") if not candidate.is_file(): raise FileNotFoundError("Document not found") return candidate.read_text(encoding="utf-8")For stronger isolation, map validated identifiers to predefined paths and ensure the server process runs with minimal filesystem privileges.
