fsguard-mcp
fsguard-mcp
Ein Dateisystem- und Git-MCP-Server, der jeden Vorgang auf einen zulässigen Verzeichnisbaum beschränkt – mit symlink-aufgelöster Pfad-Containment, nicht per String-Präfix-Matching.
Warum es das gibt
Anthropics eigene offizielle Dateisystem- und Git-MCP-Server (@modelcontextprotocol/server-filesystem, Teil von modelcontextprotocol/servers, 89.7k★) haben in zehn Monaten fünf separate Pfad-Containment-CVEs über zwei Server hinweg aufgewiesen – und das Muster ist weiterhin aktiv:
CVE-2025-53109 / CVE-2025-53110 (Dateisystem, CVSS 8.4/7.3) – der „allowed directory“-Check verwendete ein naives
startsWith()-Präfix-Matching, das durch Symlinks und durch Geschwisterverzeichnisse ausgehebelt wird, die lediglich ein String-Präfix teilen (z. B. passt ein erlaubtes/home/user-safeauch auf/home/user-safe-evil), was dateisystemweiten Lese-/Schreibzugriff und einen dokumentierten RCE-Pfad ermöglicht.CVE-2025-68143 / CVE-2025-68144 / CVE-2025-68145 (git) –
git_initakzeptierte beliebige unvalidierte Pfade,git_diff/git_checkoutübergaben nutzerkontrollierte Argumente direkt an diegit-CLI (Argument-Injection), und der--repository-beschränkte Modus hat nicht tatsächlich verifiziert, dassrepo_pathinnerhalb des eingeschränkten Verzeichnisses bleibt.CVE-2026-27735 (git, etwa zwei Monate vor Projektstart offengelegt) –
git_add, implementiert über GitPythonsrepo.index.add(), erzwingt keine Arbeitsbaumgrenzen für../-artige Pfade, sodass Dateien außerhalb des Repos gestated und exfiltriert werden können.Eine dokumentierte RCE-Kette:
git_initin einem beschreibbaren Verzeichnis → eine bösartige.git/configmit einem „clean“-Filter → eine.gitattributes, die diesen anwendet →git_addlöst den Filter aus → ein beliebiger Shell-Befehl wird ausgeführt.
Jede dieser Lücken wurde mit einem weiteren String-/Präfix-Check gepatcht, der an genau diese eine Funktion angeschraubt wurde. Niemand hat die Grenzdurchmesserung an einen Ort verschoben, an dem ein neues Tool sie nicht einfach vergessen kann – genau so ist die vierte CVE vier Monate nach der „Behebung" der ersten drei entstanden.
Related MCP server: Local Files MCP Server
Wie sich fsguard-mcp unterscheidet
Eine Sicherheitsprimitive, die überall verwendet wird. Jedes Tool – Dateisystem oder git – löst sein Zielpfad vor allem anderen über dieselbe
ConfinedRootauf (sieheconfined_path.py). Es gibt keinen Pfad-Check pro Tool, den man vergessen könnte.Symlink-aufgelöste, komponentenbasierte Containment – kein String-Matching. Ein Pfad ist nur dann innerhalb der Root, wenn sein vollständig aufgelöster realer Pfad (alle Symlinks nachverfolgt) ein realer, relativ zum Vorfahren bestimmter Unterpfad der eigenen aufgelösten realen Root ist, geprüft mit
Path.is_relative_to()auf aufgelösten Pfaden – niemals mitstartsWith()auf einem String. Das allein schließt den genauen Fehlermodus von CVE-2025-53109/53110:/allowed-evilkann einen Containment-Check gegen eine aufgelöste Root/allowednicht passieren, weil Pfadkomponenten-Vergleich kein String-Präfix-Vergleich ist.Kein Auslagern an die
git-CLI für Inhalte – jemals. Git-Operationen laufen überdulwich– eine reine Python-Git-Implementierung ohne Subprozess und ohneargvaus Nutzereingaben für irgendetwas Inhaltsbezogenes und (entscheidend) ohneisan/smudge-Filterausführung, worauf die dokumentierte RCE-Kette angewiesen ist. Es gibt keine Argument-Injection-Oberfläche, weil keine Argumentliste zu diesen Feeds Auslesen/Schreiben von Datei an einen externen Prozess übergeben wird. (dulwich führtpre-commit/commit-msg/post-commit-Hooks übersubprocess.call()aus, falls sie existieren – echte Prozessausführung, die nichts mit Inhaltsfilter zu tun haben.git_commitübergibt für wirklich jeden Fallno_verify=True, um routinemäßig zu überspringen, statt sich darauf zu verlassen, dass sie zufällig nicht ausführbar sind.)Schreiboperationen validieren auch das übergeordnete Verzeichnis, nicht nur einen bestehenden Zielpfad – das schließt die Fehlerklasse, bei der das Ziel noch nicht existiert (weshalb „löst dieser Pfad innerhalb der Root auf" nur mit einem nicht existierenden Pfad geprüft und daher nicht symlink-aufgelöst werden konnte), sein übergeordnetes Verzeichnis jedoch selbst ein Symlink nach außen ist. Nicht existierende Pfadsegmente werden vor alle diesem lexikalisch normalisiert (
./..als reine Pfad-Algebra kollabiert), und zwar unabhängig davon, was scheibenseitig existiert. Eine genauere früh Version dieses Projekts hat die Containment vor der Normalisierung geprüft, was zufällig all ihre Tests auf Windows bestand (deren Pfad-APIs..für einen normalisieren), auf Linux/macOS aber umgbar war. Das ist inzwischen behoben, und es gibt genau für diesen Fall Tests – ist aber der Grund, warum dieses Projekt „die Tests sind auf meinem Rechner grün" mit echtem Misstrauen betrachtet..git/configkann den Betrieb nicht aus der Root herauslenken. dulwich respektiert den eigenständigencore.worktree-Konfigurationseintrag eines Repos, und jede Git-Operation öffnet eine zweiteRepo-Instanz intern aus einem Pfad-String – ein Aufrufer konnte also eine.git/configmitcore.worktreeschreiben, die irgendwohin zeigt, und jedes darauffolgende Git-Tool würde still außerhalb der eingeschränkten Root arbeiten, unsichtbar für den Pfad-Check (der das eingeschränkte Repo-Verzeichnis sieht, nie wohin dulwich tatsächlich umgeleitet hat). Das fiel erst der zweiten Sicherheitsrunde dieses Projekts auf – ein echtes Lese-/Exfiltrations-grundlegender, das nur die offengelegten Tools dieses Servers nutzt, schwerwiegender als jede zur Behebung gedachte CVE. Jedes Git-Tool weigert sich inzwischen, ein Repo zu öffnen, dessen Konfigurationcore.worktreeüberhaupt gestiert, und prüft zusätzlich unabhängig, dass das eigentlicheRepo-Objekt, das es geöffnet hat, seinen Arbeitspfad als das exakte validierte Verzeichnis absagt.UNC-Pfade und Cross-Drive-Pfade werden abgelehnt, bevor überhaupt Netzwerk oder Festplatte berührt wird. Das Auflösen eines
\\host\share\...-Pfads lässt Windows tatsächlich eine SMB-Verbindung versuchen – und Windows versucht, diese Verbindung als der Serverprozess zu authentifizieren, das ist das „forced ncml Auth via UNC path"-Verfahrenus zum Klau von Anmeldedaten, ganz abgesehen davon, dass unerreichbare Hosts einen vollständigen Verbindungs-Timeout blockiert. Ein Kandidat, der auf einer anderen physischen Einheit oder einem anderen Host als der eingeschränkten Root verankert ist, wird jetzt anhand eines billigen String-Vergleichs abgelehnt, bevor überhaupt Dateisystem oder Netzwerk angeführt werden. Auch NTFS-Alternative-Datastreams (file.txt:hidden) werden grundsätzlich abgelehnt – sie sind in Verzeichnislisten unsichtbar, bleiben jedoch über denselben Pfadstring vollständig lesbar/schreibbar und können das Fehlen der Windows-„Mark of the Web"-Downloadwarnung vortäuschen.
Tools
Tool | Task |
| Textdatei lesen |
| Textdatei erstellen oder überschreiben |
| Einträge eines Verzeichnisses auflisten |
| Dateien finden, die einem Glob-Muster entsprechen, rekursiv |
| Datei bewegen/umbenennen |
| Ein git-Repository initialisieren |
| Gested/unstaged/unverfolgte Dateien |
| Dateien stagen |
| Gestagte Änderungen committen |
| Einen Diff anzeigen |
| Commit-Historie anzeigen |
Einrichtung
pip install fsguard-mcp
export FSGUARD_ROOT="/path/to/the/one/directory/tree/this/server/may/touch"
fsguard-mcpFSGUARD_ROOT ist erforderlich – es gibt keinen Standardwert, und der Server weigert sich, einen zu raten. Weisen Sie Ihren MCP-Client den Befehl fsguard-mcp verwenden und setzen Sie FSGUARD_ROOT in seiner Umgebungskonfiguration.
Tests
pip install -e ".[dev]"
pytest tests/ -vAlle 68 Tests sind in sich geschlossen (echte Temp-Verzeichnisse, echte Symlinks, echte Git-Repos) – keine externen Dienste nötig.
Bekannte Einschränkung
Zuerst wird die Containment geprüft, dann läuft die Dateisystemoperation ab – zwischen beiden gibt es eine inhäente TOCTOU-Lücke (time-of-check-to-time-of-use). Ein paralleler Prozess mit Schreibzugriff auf den Baum der eingeschränkten Root könnte in diesem Fenster im Prinzip jedes beliebige einen Symlink austauschen (während des Reviews ein funktionierenden Proof of Concept). Das vollständige Schließen erfordert ein Primitiv auf OS-Ebene (z. B. Linux openat2(RESOLVE_BENEATH), einen echten Mount-Namespace), eine leistungsfähige portable Python-Lösung gibt es in dieser Hinsicht nicht; die Garantie dieses Projekts lautet „korrekte Containment-Logik, unmittelbar vor der Verwendung geprüft", nicht „immun gegen einen Angreifer, der bereits innerhalb der Root schreiben kann."
Status
v0.1.0, live auf PyPI. OPs. Aus bestehende Tests (Unit-Tebene, mit echten Symlinks und echten Git-Repos) – nicht nur String-Logik-Behauptungen.) Zwei Runden analytischer Sicherheitsprüfung vor dem ersten Commit; beide fanden echte, funktionierende Bypasses (ein ..-Traversal-Ausbruch über noch nicht existierende Pfade auf dem Windows und die core.worktree-Weiterleitung oben, unter kleineren Funden), die inzwischen behoben sind, mit Tests am gegen damit den gemeldeten Exploit abgesichert und auf der Grundlage frischer pip install des veröffentlichten Pakets erneut verifiziert.
Lizenz
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