
Готовое исправление для неисправленной уязвимости внедрения команд MCP STDIO (семейство CVE-2026-30623)
Готовое исправление для непатченной уязвимости инъекции команд в MCP STDIO (семейство CVE-2026-30623, раскрытое OX Security в апреле 2026 года как «by design» — патча SDK не будет). Добавьте одну строку импорта — и каждый stdio MCP-сервер, запускаемый вашим Python-приложением, будет проверяться по команде/аргументам/окружению до того, как ОС породит процесс.
Если вы здесь впервые, сначала прочитайте Область применения, затем Установка и Начало работы — они обеспечат вашу защиту менее чем за две минуты.
Pre-1.0, идёт активная разработка.
check/launch/rules) реализованы и покрыты автоматическим набором тестов, которые выполняются против реальных бинарных файлов, установленных на тестовой машине (python, node, npx), — не моков, — включая настоящее сквозное MCP-рукопожатие через реальный запускаемый серверный фикстур и настоящий тест launch на уровне субпроцесса.Что входит в область применения: валидация запуска stdio MCP-сервера (команда + аргументы + окружение) до того, как он достигнет уровня порождения процессов ОС, — в частности для закрытия пути инъекции команд/аргументов, описанного в SECURITY.md.
Что явно вне области применения: сканирование объявленных инструментов сервера на опасные возможности (это другая проблема — см. AgentGuard), помещение запущенного процесса в песочницу и не-stdio (SSE/HTTP) MCP-транспорты.
git clone <this-repo>
cd mcpshield
pip install -e . # core CLI: click + rich only
pip install -e ".[mcp]" # if you also want the Python autopatch (needs the `mcp` SDK)
Проверьте, что всё работает:
mcpshield --version
mcpshield --help
Если ваше приложение написано на Python и само создаёт StdioServerParameters / вызывает mcp.client.stdio.stdio_client, добавьте один импорт в самый верх вашей точки входа — до того, как что-либо ещё импортирует mcp.client.stdio:
import mcpshield.autopatch # side-effect import; must come first
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# ... use stdio_client exactly as before -- it's now validated
Теперь небезопасный запуск вызывает mcpshield.core.errors.UnsafeConfigurationError (подкласс ValueError) вместо порождения процесса.
Проверьте конфигурационный файл в стиле mcpServers, ничего не запуская:
mcpshield check claude_desktop_config.json
+---------------------------------------------------------------+
| Server | Status | Command | Detail |
|------------------+---------+---------+------------------------|
| filesystem | OK | npx | - |
| evil-server | BLOCKED | npx | Argument '...' contains|
| | | | shell metacharacter |
+---------------------------------------------------------------+
1 ok, 0 warned, 1 blocked
Завершается с ненулевым кодом, если что-либо имеет статус BLOCKED (добавьте --strict, чтобы также завершаться с ошибкой при WARN) — можно сразу встраивать в CI.
Для MCP-клиента (Node, Java, Rust, ...), который не может использовать Python-автопатч, укажите в его конфиге mcpshield вместо реальной команды:
{
"command": "mcpshield",
"args": ["launch", "--", "npx", "-y", "some-mcp-server"]
}
launch выполняет валидацию, затем запускает реальную команду с тем же stdio, которого ожидает ваш MCP-клиент (прозрачная передача), — или отказывается с понятной ошибкой, если запуск небезопасен.
| Проверка | Нативный бинарный файл (например, python.exe) | Интерпретируемый оболочкой (.cmd/.bat/shebang-скрипт) |
|---|---|---|
Метасимволы оболочки (&, |, ;, обратный апостроф, $(...), ...) в аргументе | Разрешено | Заблокировано |
| NUL-байт / перевод строки в аргументе | Заблокировано | Заблокировано |
Команда разрешается через относительный обход пути (..) | Заблокировано | Заблокировано |
| Команда не разрешается в реальный файл | Заблокировано | Заблокировано |
LD_PRELOAD / NODE_OPTIONS / и т.п. в окружении | Удаляется (предупреждение) | Удаляется (предупреждение) |
PYTHONPATH в окружении | Помечается (предупреждение), не удаляется | Помечается (предупреждение), не удаляется |
Нативные бинарные файлы получают менее строгие проверки аргументов, поскольку они выполняют exec напрямую — оболочки, которая заново разбирала бы список аргументов, нет. Команды, интерпретируемые оболочкой (чаще всего npx.cmd/npx.bat в Windows), получают строгие проверки, потому что это и есть тот самый механизм, который эксплуатирует соответствующая CVE.
Оба варианта — это осознанные исключения, включаемые для конкретных значений, а не универсальный флаг «отключить проверки»:
allow_raw_args=["--some-value-with-a-pipe"] (библиотека) освобождает конкретные значения аргументов, которые вы проверили и которым доверяете.allow_env=["SOME_VAR"] позволяет переменной окружения, которая обычно удаляется, проходить без изменений.| Команда | Что делает |
|---|---|
mcpshield check <config> [--format table|json] [--strict] | Статическая проверка конфига mcpServers. Ничего не выполняет. Ненулевой код возврата при любом BLOCKED (а с --strict — и при WARN). |
mcpshield launch -- <command> [args...] | Выполняет валидацию, затем запускает реальную команду с прозрачной передачей stdio. |
mcpshield rules list | Показывает активный блок-лист метасимволов оболочки, списки переменных окружения и известные безопасные бинарные файлы-лаунчеры. |