
Drop-in-Fix für die ungepatchte MCP STDIO Command-Injection-Schwachstelle (CVE-2026-30623-Familie)
Ein Drop-in-Fix für die nicht gepatchte MCP-STDIO-Befehlsinjektionslücke (die CVE-2026-30623-Familie, von OX Security im April 2026 als "by design" offengelegt – es kommt kein SDK-Patch). Importieren Sie eine Zeile, und jeder stdio MCP-Server, den Ihre Python-Anwendung startet, erhält eine Validierung von Befehl/Argumenten/Umgebung, bevor das Betriebssystem überhaupt einen Prozess erzeugt.
Wenn Sie neu hier sind, lesen Sie zuerst Geltungsbereich, dann werden Installation und Erste Schritte Sie in unter zwei Minuten schützen.
Vor 1.0, aktiv entwickelt.
check/launch/rules) sind
implementiert und werden von einer automatisierten Testsuite abgedeckt, die
gegen die echten, auf dem Testrechner installierten Binärprogramme (python,
node, npx) läuft – keine Mocks – einschließlich eines echten End-to-End-MCP-Handshakes
durch eine echte gestartete Server-Fixtur und eines echten Subprozess-Tests von launch.Im Geltungsbereich: Validieren des Starts eines stdio MCP-Servers (Befehl + Argumente + Umgebung), bevor er die Betriebssystem-Prozessstartebene erreicht, um insbesondere den Befehls-/Argument-Injektionspfad zu schließen, der in SECURITY.md beschrieben ist.
Ausdrücklich ausgeschlossen: Scannen der deklarierten Werkzeuge eines Servers auf riskante Fähigkeiten (das ist ein anderes Problem – siehe AgentGuard), Sandboxing des gestarteten Prozesses und Nicht-STDIO-Transporte (SSE/HTTP) für MCP.
git clone <this-repo>
cd mcpshield
pip install -e . # Kern-CLI: click + rich only
pip install -e ".[mcp]" # falls Sie auch den Python-Autopatch möchten (benötigt das `mcp`-SDK)
Überprüfen, ob es funktioniert hat:
mcpshield --version
mcpshield --help
Wenn Ihre Anwendung in Python geschrieben ist und StdioServerParameters erstellt /
mcp.client.stdio.stdio_client selbst aufruft, fügen Sie ganz oben in Ihrem Einstiegspunkt
einen Import hinzu – bevor irgendetwas anderes mcp.client.stdio importiert:
import mcpshield.autopatch # Seitenwirkungsimport; muss als erstes kommen
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# ... verwenden Sie stdio_client genau wie zuvor – es ist jetzt validiert
Ein unsicherer Start löst nun mcpshield.core.errors.UnsafeConfigurationError
(eine ValueError-Unterklasse) aus, anstatt jemals einen Prozess zu starten.
Auditieren Sie eine mcpServers-Konfigurationsdatei, ohne etwas auszuführen:
mcpshield check claude_desktop_config.json
+---------------------------------------------------------------+
| Server | Status | Befehl | Detail |
|------------------+---------+--------+------------------------|
| filesystem | OK | npx | - |
| evil-server | BLOCKED | npx | Argument '...' enthält |
| | | | Shell-Metazeichen |
+---------------------------------------------------------------+
1 ok, 0 gewarnt, 1 blockiert
Beendet sich mit einem Nicht-Null-Exitcode, wenn etwas BLOCKED ist (fügen Sie --strict hinzu, um auch bei WARN zu scheitern) – setzen Sie es direkt in CI ein.
Für einen MCP-Client (Node, Java, Rust, …), der den Python-Autopatch nicht verwenden kann,
konfigurieren Sie ihn so, dass er auf mcpshield verweist anstatt auf den eigentlichen Befehl:
{
"command": "mcpshield",
"args": ["launch", "--", "npx", "-y", "some-mcp-server"]
}
launch validiert und führt dann den eigentlichen Befehl mit dem gleichen stdio aus,
das Ihr MCP-Client erwartet (transparente Durchleitung) – oder lehnt mit einer klaren
Fehlermeldung ab, wenn der Start unsicher ist.
Native Binärprogramme erhalten lockerere Argumentprüfungen, da sie direkt exec ausführen –
es gibt keine Shell, die die Argumentliste neu parst. Shell-interpretierbare
Befehle (am häufigsten npx.cmd/npx.bat unter Windows) erhalten strenge Prüfungen,
da dies genau der Mechanismus ist, den die zugrunde liegende CVE ausnutzt.
Beides sind bewusste, wertbezogene Opt-ins – niemals ein pauschales "Checks deaktivieren"-Flag:
allow_raw_args=["--some-value-with-a-pipe"] (Bibliothek) befreit bestimmte Argument-Werte,
die Sie überprüft haben und denen Sie vertrauen.allow_env=["SOME_VAR"] erlaubt einer normalerweise entfernten Umgebungsvariablen,
unverändert durchgelassen zu werden.git clone.mcp.client.stdio.stdio_client, so wie es zum Zeitpunkt des Patchens nachgeschlagen wird. Code, der bereits seine eigene Referenz hält (via
from mcp.client.stdio import stdio_client, ausgeführt vor
import mcpshield.autopatch), umgeht es – importieren Sie mcpshield.autopatch
immer zuerst.check löst Befehle mit dem Rechner auf, auf dem es läuft. Eine Konfiguration, die sich
auf dem Rechner, auf dem sie tatsächlich bereitgestellt wird, anders auflösen würde
(anderer PATH, andere installierte Tools), kann dort anders melden.mcpshield/
autopatch.py # Einzeilen-Import-Fix für Python-MCP-Hosts
core/
validate.py # die Validierungs-Engine (Befehls-/Argumente-/Umgebungsprüfungen)
rules.py # Blocklisten-/Erlaubnislistendaten
errors.py # UnsafeConfigurationError
cli/
main.py
commands/ (check.py, launch.py, rules.py)
tests/
fixtures/ # echte harmlose MCP-Server + Beispiel-/bösartige Konfigurationen
pip install -e ".[dev,mcp]"
pytest
Die Testsuite validiert gegen die echten python/node/npx-Binärprogramme,
die auf dem Rechner installiert sind, auf dem sie läuft (auf die gleiche Weise aufgelöst,
wie die Engine sie selbst auflöst), und enthält einen echten End-to-End-MCP-Handshake
durch eine echte gestartete Server-Fixtur – keine Mocks.
| Prüfung | Natives Binärprogramm (z. B. python.exe) | Shell-interpretierbar (.cmd/.bat/Shebang-Skript) |
|---|
Shell-Metazeichen (&, |, ;, Backtick, $(...), …) in einem Argument | Erlaubt | Blockiert |
| NUL-Byte / Zeilenumbruch in einem Argument | Blockiert | Blockiert |
Befehl wird über relativen Pfad-Traversal aufgelöst (..) | Blockiert | Blockiert |
| Befehl wird nicht zu einer echten Datei aufgelöst | Blockiert | Blockiert |
LD_PRELOAD / NODE_OPTIONS / usw. in der Umgebung | Entfernt (Warnung) | Entfernt (Warnung) |
PYTHONPATH in der Umgebung | Gekennzeichnet (Warnung), nicht entfernt | Gekennzeichnet (Warnung), nicht entfernt |
| Befehl | Was er tut |
|---|
mcpshield check <config> [--format table|json] [--strict] | Statische Prüfung einer mcpServers-Konfiguration. Führt nie etwas aus. Nicht-Null-Exit bei jedem BLOCKED (oder auch bei WARN, mit --strict). |
mcpshield launch -- <command> [args...] | Validiert, führt dann den eigentlichen Befehl mit Durchleitungs-stdio aus. |
mcpshield rules list | Zeigt die aktive Shell-Metazeichen-Blocklist, Umgebungsvariablenlisten und bekannte sichere Launcher-Binärprogramme an. |