
Correção plug-and-play para a falha de injeção de comandos MCP STDIO ainda não corrigida (família CVE-2026-30623)
Um substituto direto para a falha não corrigida de injeção de comandos MCP STDIO (a família CVE-2026-30623, divulgada pela OX Security em abril de 2026 como "by design" -- nenhum patch de SDK virá). Importe uma linha, e todo servidor stdio MCP que sua aplicação Python iniciar terá seu comando/args/env validado antes de o SO criar qualquer processo.
Se você está chegando agora, leia Escopo primeiro; depois, Instalação e Começando deixarão você protegido em menos de dois minutos.
Pré-1.0, em desenvolvimento ativo.
check/launch/rules) estão
implementados e cobertos por uma suíte de testes automatizada que roda contra os
binários reais instalados na máquina de teste (python, node, npx) --
não mocks -- incluindo um handshake MCP genuíno de ponta a ponta por meio de um
fixture de servidor real iniciado, e um teste genuíno de nível de subprocesso para launch.No escopo: validar a execução de um servidor MCP stdio (comando + args + env) antes que ela chegue à camada de criação de processos do SO, especificamente para fechar o caminho de injeção de comando/argumento descrito em SECURITY.md.
Explicitamente fora do escopo: escanear as ferramentas declaradas de um servidor em busca de capacidades arriscadas (esse é um problema diferente -- veja AgentGuard), isolar em sandbox o processo iniciado e transportes MCP não-stdio (SSE/HTTP).
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)
Verifique se funcionou:
mcpshield --version
mcpshield --help
Se seu aplicativo é escrito em Python e constrói StdioServerParameters /
chama mcp.client.stdio.stdio_client diretamente, adicione um import bem no topo
do seu entrypoint -- antes de qualquer outra coisa importar 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
Uma execução insegura agora levanta mcpshield.core.errors.UnsafeConfigurationError
(uma subclasse de ValueError) em vez de jamais criar um processo.
Audite um arquivo de configuração no estilo mcpServers sem executar nada:
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
Encerra com código de saída não zero se qualquer item estiver BLOCKED (adicione
--strict para também falhar em WARN) -- coloque isso direto no CI.
Para um cliente MCP (Node, Java, Rust, ...) que não pode usar o autopatch Python,
aponte a configuração dele para mcpshield em vez do comando real:
{
"command": "mcpshield",
"args": ["launch", "--", "npx", "-y", "some-mcp-server"]
}
launch valida e depois executa o comando real com o mesmo stdio que seu cliente MCP
espera (passagem transparente) -- ou recusa com um erro claro se a execução for insegura.
Binários nativos recebem verificações de argumento mais flexíveis porque fazem exec
diretamente -- não há shell para reinterpretar a lista de argumentos. Comandos
interpretáveis por shell (mais comumente npx.cmd/npx.bat no Windows) recebem
verificações rigorosas porque esse é exatamente o mecanismo que a CVE subjacente explora.
Ambas as opções são opt-ins deliberados, por valor -- nunca uma flag genérica de "desativar verificações":
allow_raw_args=["--some-value-with-a-pipe"] (biblioteca) isenta valores de argumento específicos que você revisou e nos quais confia.allow_env=["SOME_VAR"] permite que uma variável de ambiente normalmente removida passe sem modificações.git clone.mcp.client.stdio.stdio_client conforme resolvido no momento da correção. Código que já mantém sua própria referência (via from mcp.client.stdio import stdio_client executado antes de import mcpshield.autopatch) vai contorná-lo -- importe mcpshield.autopatch primeiro, sempre.check resolve comandos usando a máquina em que é executado. Uma configuração que resolveria de forma diferente na máquina em que é realmente implantada (um PATH diferente, ferramentas instaladas diferentes) pode relatar de forma diferente lá.mcpshield/
autopatch.py # one-line-import fix for Python MCP hosts
core/
validate.py # the validation engine (command/args/env checks)
rules.py # blocklist/allowlist data
errors.py # UnsafeConfigurationError
cli/
main.py
commands/ (check.py, launch.py, rules.py)
tests/
fixtures/ # real benign MCP server + sample/malicious configs
pip install -e ".[dev,mcp]"
pytest
A suíte de testes valida contra os binários reais python/node/npx instalados na
máquina em que é executada (resolvidos da mesma forma que o próprio mecanismo os resolve),
e inclui um handshake MCP genuíno de ponta a ponta por meio de um fixture de servidor real
iniciado -- não mocks.
| Verificação | Binário nativo (ex.: python.exe) | Interpretável por shell (.cmd/.bat/script shebang) |
|---|
Metacaracteres de shell (&, |, ;, backtick, $(...), ...) em um argumento | Permitido | Bloqueado |
| Byte NUL / nova linha em um argumento | Bloqueado | Bloqueado |
Comando resolve via path traversal relativo (..) | Bloqueado | Bloqueado |
| Comando não resolve para um arquivo real | Bloqueado | Bloqueado |
LD_PRELOAD / NODE_OPTIONS / etc. no env | Removido (aviso) | Removido (aviso) |
PYTHONPATH no env | Sinalizado (aviso), não removido | Sinalizado (aviso), não removido |
| Comando | O que faz |
|---|
mcpshield check <config> [--format table|json] [--strict] | Auditoria estática de uma configuração mcpServers. Nunca executa nada. Saída não zero em qualquer BLOCKED (ou também WARN, com --strict). |
mcpshield launch -- <command> [args...] | Valida e depois executa o comando real com stdio em modo passagem. |
mcpshield rules list | Mostra a lista de bloqueio ativa de metacaracteres de shell, as listas de variáveis de ambiente e os binários de inicialização seguros conhecidos. |