Skip to content

filesystem: allowed directories are trimmed after realpath, so a name ending in a space or quote allows its sibling #5320

Open

Description

@cliffhall

Problem

normalizePath (src/filesystem/path-utils.ts) trims surrounding whitespace and strips a leading or trailing quote before formatting a path. That suits a path a person typed, but it is also applied to the realpath of each allowed directory:

  • parseRootUri in src/filesystem/roots-utils.ts (the resolved form of a client Root), and
  • resolveAllowedDirectories in src/filesystem/index.ts (both forms of a command-line directory).

Trailing spaces and quotes are legal in POSIX filenames. If an allowed directory's real name ends in one (say /work/project ), the allow-list gets the trimmed name (/work/project), which is a different directory. A sibling with that name then passes the containment checks in validatePath, so its files can be read and written although it was never allowed.

How to reproduce

On macOS or Linux: create /tmp/x/project (trailing space) and /tmp/x/project with a file in it. Advertise the Root file:///tmp/x/project%20 from a 2025-era client (or pass "/tmp/x/project " on the command line). list_allowed_directories shows /tmp/x/project, and read_text_file /tmp/x/project/<file> succeeds.

Expected

A path the server got from fs.realpath (or a Root's advertised spelling) is formatted with normalizePathFormat, never trimmed, so the allow-list names exactly the directory that was allowed. Whether command-line arguments should still be trimmed (shell quoting leftovers) is a separate call; their resolved form should not be.

Context

Found in the Copilot review of #5317 (#5183), which keeps a Root's advertised form verbatim for this reason (it uses normalizePathFormat) but leaves the resolved form and index.ts as they were, since changing them is outside that issue. #5185 is changing both functions' realpath handling, so this should land after it.

Activity

  1. added this to the v2.3.0 milestone on Oct 27, 2026
  2. added
    bugSomething isn't working
    server-filesystemReference implementation for the Filesystem MCP server - src/filesystem
    on Oct 27, 2026
  3. FelixFangX commented on Oct 27, 2026

    @FelixFangX

    Ready fix on a fork branch (this repository currently limits opening PRs to collaborators):

    https://github.com/FelixFangX/servers/tree/fix/filesystem-realpath-no-trim

    Compare: v2/main...FelixFangX:fix/filesystem-realpath-no-trim

    • parseRootUri resolved form → normalizePathFormat
    • resolveAllowedDirectories both forms → normalizePathFormat
    • stdio test for trailing-space allow-list vs sibling

    Happy for a maintainer to cherry-pick or open from the branch if external PRs stay restricted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingserver-filesystemReference implementation for the Filesystem MCP server - src/filesystemv2

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions