modelcontextprotocol / modelcontextprotocol/servers
filesystem: FS_SEARCH_EXCLUDE_PREFIXES is lexical; should excludes be canonical/symlink-aware?
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 90.5k
- Forks
- 11.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 5
Description
Context. The proposed fix for #4162 (PR #4212) adds FS_SEARCH_EXCLUDE_PREFIXES as a fast lexical prefilter that refuses recursive search_files / directory_tree on configured slow roots, typically macOS CloudStorage / FileProvider paths.
Discussion on #4162 surfaced that the check is purely lexical: a symlink such as /allowed/sneaky whose target lives under an excluded prefix is not caught by the prefix check, and may still reach the slow provider path during canonicalisation / validation.
The case for keeping the #4162 fix scoped to the lexical prefilter, as discussed in that thread:
- The bypass is pre-existing behaviour — the original
searchFilesWithValidationexclude check is also lexical. validatePathcontinues to enforce theallowed_directoriesescape boundary via its ownrealpath, so the security boundary is unaffected. This question is about whether excludes should be symlink-aware.- The impact of the bypass is performance / hang risk from reaching a slow provider path, not an authorization bypass.
- An unbounded
realpath-before-compare exclude check risks re-introducing the kind of hang #4162 is trying to avoid.
Design question. Should excludes be hardened against symlink bypass?
One possible shape is two-stage:
- Fast lexical check first, preserving current cheap behaviour.
- If not excluded lexically, optionally perform bounded canonicalisation, e.g.
withFsTimeout(fs.realpath(...)), then re-check the canonical path against excluded prefixes, with an explicit fail-policy on timeout — deny, allow, or return a typed error.
This affects both search_files and directory_tree, so it seems like a design decision rather than a drop-in fix. Not gating #4162; filing this separately so the symlink-aware exclude question is not lost.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the discussion in #4162 and PR #4212, then trace the search_files and directory_tree entry points and their existing lexical exclusion and validation behavior. Compare bounded canonicalisation options and timeout policies for both paths. Done means a documented design decision that addresses symlink bypasses without restoring unbounded slow-provider access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 38/100