Skip to content

Security: Path Traversal bypass in file read operations #10

@8endit

Description

@8endit

Summary

The is_path_allowed() security check can be bypassed using relative path traversal sequences, allowing file reads outside the configured working directory.

Affected Functionality

File read operations via the read_file tool. The server advertises "Strict file path security (only within the working directory)" in its README.

Steps to Reproduce

  1. Start the server with --dir /tmp/testdir
  2. Call the read_file tool with path ../../../etc/passwd
  3. The server returns the contents of /etc/passwd

Root Cause

The is_path_allowed() function appears to check the path string before fully resolving it. A relative path like ../../../etc/passwd bypasses the check because the path is not normalized (e.g., via os.path.realpath() or pathlib.Path.resolve()) before the allowlist comparison.

Suggested Fix

Resolve the absolute path before checking against the allowed directory:

import os

def is_path_allowed(path: str, working_dir: str) -> bool:
    resolved = os.path.realpath(os.path.join(working_dir, path))
    return resolved.startswith(os.path.realpath(working_dir))

Impact

Any user running this server with the default configuration could have files outside the working directory read by an LLM agent or a malicious prompt. This is especially relevant in multi-user or shared environments.

Disclosure Timeline

  • 2026-04-01: Vulnerability discovered via dynamic security testing
  • 2026-04-01: Reported to maintainer (this issue)
  • 2026-05-01: Planned public disclosure (30 days)

I'm happy to help with testing a fix if needed. Found using mcpfuzz — a dynamic security testing tool for MCP servers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions