Skip to main content
Glama

fsguard-mcp

PyPI

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-safe auch 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_init akzeptierte beliebige unvalidierte Pfade, git_diff/git_checkout übergaben nutzerkontrollierte Argumente direkt an die git-CLI (Argument-Injection), und der --repository-beschränkte Modus hat nicht tatsächlich verifiziert, dass repo_path innerhalb des eingeschränkten Verzeichnisses bleibt.

  • CVE-2026-27735 (git, etwa zwei Monate vor Projektstart offengelegt) – git_add, implementiert über GitPythons repo.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_init in einem beschreibbaren Verzeichnis → eine bösartige .git/config mit einem „clean“-Filter → eine .gitattributes, die diesen anwendet → git_add lö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

  1. Eine Sicherheitsprimitive, die überall verwendet wird. Jedes Tool – Dateisystem oder git – löst sein Zielpfad vor allem anderen über dieselbe ConfinedRoot auf (siehe confined_path.py). Es gibt keinen Pfad-Check pro Tool, den man vergessen könnte.

  2. 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 mit startsWith() auf einem String. Das allein schließt den genauen Fehlermodus von CVE-2025-53109/53110: /allowed-evil kann einen Containment-Check gegen eine aufgelöste Root /allowed nicht passieren, weil Pfadkomponenten-Vergleich kein String-Präfix-Vergleich ist.

  3. Kein Auslagern an die git-CLI für Inhalte – jemals. Git-Operationen laufen über dulwich – eine reine Python-Git-Implementierung ohne Subprozess und ohne argv aus Nutzereingaben für irgendetwas Inhaltsbezogenes und (entscheidend) ohne isan/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ührt pre-commit/commit-msg/post-commit-Hooks über subprocess.call() aus, falls sie existieren – echte Prozessausführung, die nichts mit Inhaltsfilter zu tun haben. git_commit übergibt für wirklich jeden Fall no_verify=True, um routinemäßig zu überspringen, statt sich darauf zu verlassen, dass sie zufällig nicht ausführbar sind.)

  4. 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.

  5. .git/config kann den Betrieb nicht aus der Root herauslenken. dulwich respektiert den eigenständigen core.worktree-Konfigurationseintrag eines Repos, und jede Git-Operation öffnet eine zweite Repo-Instanz intern aus einem Pfad-String – ein Aufrufer konnte also eine .git/config mit core.worktree schreiben, 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 Konfiguration core.worktree überhaupt gestiert, und prüft zusätzlich unabhängig, dass das eigentliche Repo-Objekt, das es geöffnet hat, seinen Arbeitspfad als das exakte validierte Verzeichnis absagt.

  6. 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

fs_read(path)

Textdatei lesen

fs_write(path, content)

Textdatei erstellen oder überschreiben

fs_list(path=".")

Einträge eines Verzeichnisses auflisten

fs_search(pattern, path=".")

Dateien finden, die einem Glob-Muster entsprechen, rekursiv

fs_move(source, destination)

Datei bewegen/umbenennen

git_init_repo(repo_path)

Ein git-Repository initialisieren

git_repo_status(repo_path="")

Gested/unstaged/unverfolgte Dateien

git_stage(repo_path, paths)

Dateien stagen

git_commit_repo(repo_path, message, author)

Gestagte Änderungen committen

git_diff_repo(repo_path=".", staged=False)

Einen Diff anzeigen

git_log_repo(repo_path=".", max_entries=10)

Commit-Historie anzeigen

Einrichtung

pip install fsguard-mcp
export FSGUARD_ROOT="/path/to/the/one/directory/tree/this/server/may/touch"
fsguard-mcp

FSGUARD_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/ -v

Alle 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

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
  • F
    license
    Not graded
    quality
    C
    maintenance
    Exposes 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.

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

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