fsguard-mcp
fsguard-mcp
Файловый и git MCP-сервер, который ограничивает каждую операцию разрешённым деревом каталогов с помощью ограничения пути на основе разрешения симлинков, а не сравнения строковых префиксов.
Почему это существует
Официальные файловый и git MCP-серверы Anthropic (@modelcontextprotocol/server-filesystem, часть modelcontextprotocol/servers, 89.7k★) за десять месяцев принесли пять отдельных CVE, связанных с ограничением пути, в двух серверах, и эта картина всё ещё актуальна:
CVE-2025-53109 / CVE-2025-53110 (filesystem, CVSS 8.4/7.3) — проверка «разрешённого каталога» использовала наивное сравнение по префиксу через
startsWith(); она обходилась с помощью симлинсков и соседних каталогов, которые просто имеют общий строковый префикс (например, разрешённый/home/user-safeтакже соответствует/home/user-safe-evil), что давало чтение/запись по всей файловой системе и документированный путь к RCE.CVE-2025-68143 / CVE-2025-68144 / CVE-2025-68145 (git) —
git_initпринимал произвольные непроверенные пути,git_diff/git_checkoutпередавали управляемые пользователем аргументы напрямую в CLIgit(инъекpling аргументов), а режим c ограничением--repositoryфактически не проверял, чтоrepo_pathостаётся внутри ограниченного каталога.CVE-2026-27735 (git, раскрыта примерно за 2 месяца до старта этого проекта) —
git_add, реализованный черезrepo.index.add()в GitPython, не обеспечивает границы рабочего дерева для путей вида../, позволяя добавлять в индекс и выносить файлы за пределы репозитория.Документированная цепочка RCE:
git_initв доступном для записи каталоге → вредоносный.git/configс фильтром "clean" →.gitattributes, который его применяет →git_addзапускает фильтр → выполняется произвольная shell-команда.
Каждую из этих уязвимых "mo2ело" закрывали другой проверкой строки/префикса, прикрученной именно к этой функции. Никто не перенёс контроль границ туда, где новый инструмент не сможет просто забыть его включить — то есть, именно так четвёртая CVE появилась через четыре месяца после «исправления» первых трёх.
Related MCP server: Local Files MCP Server
Чем fsguard-mcp отличается
Единственный примитив безопасности, используемый везде. Каждый инструмент — файловой системы или git — перед всеми остальным действиями разрешает свой целевой путь через один и тот же
ConfInedRoot(см.confined_path.py). Нет никакой отдельной проверки пути для каждого инструмента, о которой можно забыть.Контроль на основе разрешений симлинков и компонентов пути, а не строк. Путь считается находящимся внутри корня только тогда, когда его полностью разрешённый реальный путь (все симлинки раскрыты) является реальным подпутём относительно собственного разрешённого корня, и это проверяется с помощью
Path.is_relative_to()по уже разрешённым путям, а не черезstartswith()по строке. Уже это закрывает точный сценарий ломания клана CVE-2025-53109/53110:/allowed-evilне может пройти проверку, когда корень разрешается в/allowed, потому что сравнение компонентов пути — это не сравнение строковых префиксов.Никакого вызова
gitдля работы с содержимым — никогда. Операции Git выполняются черезdulwich— чисто Python-реализацию git без субпроцессов и без argv, собираемого из пользовательского ввода для чего бы то ни было, связанного с содержимым, и (что критично) без выполнения фильтров clean/smudge, а именно они нужны документированной цепочке RCE. Здесь нет поверхности для инъекции аргументов, потому что список аргументов не передаётся внешнему процессу для чтения/записи содержимого файлов. (dulwichвсё же запускает хукиpre-commit/commit-msg/post-commitчерезsubprocess.call(), если они существуют, — это действительно порождает процессы, но не связано с фильтрацией содержимого.git_commitвсегда передаётno_verify=True, чтобы категорически их пропускать, а не рассчитывать на то, что они не выполнятся.)Operations записи проверяют ещё и родительский каталог, а не только уже существующую цель. Это закрывает класс ошибок, в которых цель ещё не существует (поэтому проверка «разрешается ли путь внутри корня» выполнялась для несуществующего пути и не могла раскрыть симлинки) и родительский каталог сам является символической ссылкой наружу. Несуществующие сегменты пути нормализуются лексически (
./..сводятся как чистая алгебра пути) до всех этих проверок и независимо от того, что существует на диске. Более ранняя версия этого проекта проверяла ограничения до нормализации, и она проходила весь набор тестов в Windows (где API путей сам нормализует..за вас), оставаясь обходимой в Linux/macOS. Это уже исправлено, и для этого конкретного случая есть тесты, но именно по этой причине проект относится к «у меня на машине тесты зелёные» с настоящим подозрением..git/configне может перенаправить операции за пределы корня.dulwichсоблюдает записьcore.worktreeиз конфига репозитория, а каждая git-операция внутри себя заново открываетRepoиз строки пути — поэтому вызывающий может записать в.git/configcore.worktreeна любой путь, и каждый последующий git-инструмент будет молча работать за пределами ограниченного корня: проверка пути его не увидит, потому что ей виден только сам ограниченный каталог репозитория, а не то место, кудаdulwichна самом деле перенаправился. Это было обнаружено в собственной втором раунде ревью безопасности — реальный примитив чтения/выноса данных с помощью только этих самых декалбл инструментов, серьёзнее любой CVE, ради которого он был написан. Теперь каждый git-инструмент отказывается открывать репозиторий, у которогоcore.worktreeвообще задан, и дополнительно проверяет, что реально открытый объектRepoсообщает свой рабочий путь как тот самый прovalentённый том.UNC-пути и пути на другом диске отклоняются до каких-либо обращений к сети или диску. Резолвинг пути вида
\\host\share\...вынуждает Windows реально пытаться установить SMB-подключение, и Windows попытается авторизоватьэн это соединение от имени серверного процесса — это техника кражи учётных данных «принудительная NTLM-авторизация через UNC-путь»; и в addition block the server for the full connection timeout to an unreachable host. Любой путь, привязанный к диску или хосту, отличному от ограниченного корня, отклоняется дешёвым сравнением строк: ещё до вызова файловой системы или сети. Альтернативные потоки данных NTFS (file.txt:hidden) также отклоняются вовсе — они не видны в списках файлов, но полнорассьbиваются и читаются через ту же строку пути, и они могут подделывать отсутствие предупреждения Windows о загрузке "Mark of the Web".
Инструменты
Инструмент | Действие |
| Прочитать текстовый файл |
| Создать или перезаписать текстовый файл |
| Перечислить записи каталога |
| Рекурсивно найти файлы по glob-шаблону |
| Переместить/переименовать файл |
| Инициализировать git-репозиторий/репозиториай |
| Индексированные/неиндексированные/неотслеживаемые файлы |
| Добавить в индекс |
| Зафиксировать проиндексированных изменения (commit) |
| Показаня diff |
| Показать историю коммита |
Установка
pip install fsguard-mcp
export FSGUARD_ROOT="/path/to/the/one/directory/tree/this/server/may/touch"
fsguard-mcpFSGUARD_ROOT обязателен — значения по умолчанию нет, сервер отказывается быть его уганым. Настройте свой MCP-клиент на команду fsguard-mcp, задав FSGUARD_ROOT в его конфигурации окружения.
Тестирование
pip install -e ".[dev]"
pytest tests/ -vВсе 68 тестов автономаничны (реально создаются исные временные каталоги, исные симлинш км, настоящие git-репозирии) — ника внешние сервисы value.
Известное ограничение
Сначала выполняется проверка соответствия, потом любом работает операция с файловой системой — между ними чем закрепён в ГОТОU (time-of-check-to-time-of-use) бурый разрыв. Параллелный процесс с правом записи внутре диапагона самого ограниченного корня у принципе может подменить симлинную ссып между этой загадкой — что подтверждено рабочим proof-of-concept на время ревью. Чтобы закрыть эту forged полностью, нужен примитив уровня ОС (например, openat2(RESOLVE_BENEW) на Linux или настоящий namespace mount), ne что-то достижимое в переносимом Python. Гарант этого проекта — «корректная логика контроля границ, проверяемая сразу перед операцией», а не «отражение параллельнного атакуна account, already can write inside the root».
Статус
v0.1.0, live on PyPI. 68 проходящих тестов (модульный уровень, реальные симлинки и реальные git-репозитории создаются на диске, — не только проверки строковой логики). Проект прошёд два рауadversarial security review ещё до первого коммита; каждый из них нашёл настоящие работающие обходы (попытка выхода через .. по ещё не существующим путям на POSIX и упомянутое перенаправление core.worktree, помимо мелких находок) — всё это исправлено, покрыто тестами, написанными прямо против воспроизведения уязвируемости, и дополнительно перепроверено на чистом pip install опубликованного пакета.
Лицензия
MIT`
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables file system operations such as listing, reading, and creating files within a scoped local project directory. It provides a secure way to manage local files through standardized MCP tools built with FastMCP.
- FlicenseAqualityDmaintenanceProvides safe local file operations through MCP, including reading, writing, searching, organizing, and protected deletion with configurable path restrictions.122
- FlicenseNot gradedqualityCmaintenanceExposes a secure, path-confined bridge to a local workspace and git remotes, enabling MCP clients to search, read, write, reset files, and perform git operations.
- AlicenseNot gradedqualityAmaintenanceEnables AI clients to securely operate isolated coding workspaces with file, command, Git, and deployment tools via authenticated remote MCP.7MIT
Related MCP Connectors
A MCP server built for developers enabling Git based project management with project and personal…
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
MCP-native collaborative markdown editor with real-time AI document editing
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/BerkantACUN/fsguard-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server