
mcp-server-attestation v0.2.0
Endurecimento da cadeia de suprimentos de camada 2 para servidores MCP — manifestos de ferramentas assinados com Ed25519, atestação de spawn em tempo de execução, sanitizador de argumentos com negação por padrão. Defende contra envenenamento de marketplace + CVE-2025-69256 + CVE-2025-61591.
Parte do StudioMeyer MCP Stack — Feito em Mallorca 🌴 · ⭐ se você usar
mcp-server-attestation
Endurecimento da cadeia de suprimentos em camada 2 para servidores do Model Context Protocol. Manifestos de ferramentas assinados com Ed25519, atestação de spawn em tempo de execução, sanitizador de argumentos com negação por padrão.Resposta direta a:
- Envenenamento de marketplace da OX Security, abril de 2026 — 9 de 11 registros MCP aceitaram servidores maliciosos. A posição publicada da Anthropic: "comportamento esperado".
- CVE-2025-69256 — RCE no MCP do Serverless Framework por meio de injeção de comando em
child_process.exec(). - CVE-2025-61591 — RCE no Cursor MCP por meio de servidor malicioso instalado via OAuth com sequestro de spawn.
Este pacote oferece o que a Anthropic optou por não oferecer: verificação criptográfica de quais ferramentas um servidor tem permissão para expor e quais chamadas de spawn ele tem permissão para fazer. É uma dependência drop-in, não um substituto de runtime.
Uma nota nossa
Há dois anos viemos construindo ferramentas e sistemas para nós mesmos. O fato de este repositório ser pequeno e ter poucas estrelas não é porque ele é novo. É porque só agora decidimos compartilhar o que construímos. Não é um experimento novo, é uma história longa com um commit recente.
Amamos construir coisas e compartilhá-las. Não amamos táticas de redes sociais, growth hacks ou perseguir estrelas e seguidores. Por isso este repositório é pequeno. O código é real, é usado, as issues são respondidas. Julgue por si mesmo.
Se isso ajudar você, compartilhar, testar e dar feedback nos ajuda. Se puder ser melhor, uma issue é mais útil. Se você construir algo com isso, conte-nos em [email protected]. Isso genuinamente faz o nosso dia.
De um pequeno estúdio em Palma de Mallorca.
Pacotes (npm workspaces)
| Package | Objetivo |
|---|---|
mcp-server-attestation (packages/lib) | Biblioteca: assinatura/verificação Ed25519, schema de manifesto, sanitizador, atestador de spawn, armazenamento de confiança TOFU. |
mcp-attest-cli (packages/cli) | CLI mcp-attest: keygen, sign, verify, inspect, fingerprint, check-pin. |
mcp-attest-demo (packages/demo-server) | Servidor MCP de referência (stdio, spec 2025-06-18) expondo 5 ferramentas que demonstram a biblioteca. |
Instalação
npm install mcp-server-attestation
# CLI:
npm install -g mcp-attest-cli
# Reference MCP server:
npx mcp-attest-demo
Node 20+. Sem dependências criptográficas externas — usa primitivas Ed25519 de node:crypto.
Início rápido de servidor em cinco linhas
import { verifyManifestStrict, attestSpawnStrict, type SignedManifest } from "mcp-server-attestation";
import signed from "./signed/manifest.json" assert { type: "json" };
// 1. At startup: prove the manifest you ship is the manifest you signed.
verifyManifestStrict(signed);
// 2. Before every child_process.spawn:
attestSpawnStrict(signed as SignedManifest, { command, args });
Essa é toda a integração. Duas chamadas de função, sem SaaS, sem daemon.
Se você preferir reverificar a assinatura a cada spawn (defesa em profundidade contra um manifest não verificado ou trocado chegando ao portão de verificação), use a única chamada à prova de falhas — ela verifica e então atesta:
import { attestSpawnVerified, type SignedManifest } from "mcp-server-attestation";
attestSpawnVerified(signed as SignedManifest, { command, args });
Ferramentas (servidor de referência mcp-attest-demo)
| # | Nome | readOnlyHint | destructiveHint |
|---|---|---|---|
| 1 | attest_verify_manifest | true | false |
| 2 | attest_inspect_spawn | true | false |
| 3 | attest_generate_manifest_template | true | false |
| 4 | attest_sign_manifest | false | false |
| 5 | attest_keygen | false | false |
As anotações são honestas: attest_sign_manifest e attest_keygen gravam arquivos em disco, portanto não são somente leitura, mas não destroem dados existentes, então destructiveHint permanece false. Consulte docs/THREAT-MODEL.md para a tabela de capacidades por ferramenta.
CLI
mcp-attest keygen --out-dir ./keys --name prod
mcp-attest sign --manifest manifest.json --private-key keys/prod.key --out signed.json
mcp-attest verify --signed signed.json --pin # TOFU pin
mcp-attest verify --signed signed.json --sigstore # opt-in Rekor cross-ref
mcp-attest inspect --signed signed.json --command /usr/bin/echo --arg "hello"
mcp-attest fingerprint --public-key keys/prod.pub
mcp-attest check-pin --server my-server --signed signed.json
verify sai com o código 2 em assinatura inválida e código 3 em incompatibilidade de pin.
Compatibilidade com a especificação MCP
| Versão da especificação | Status |
|---|---|
| 2024-11-05 | analisável no manifesto, não é alvo do servidor de referência |
| 2025-03-26 | analisável no manifesto, não é alvo do servidor de referência |
| 2025-06-18 | alvo completo |
A biblioteca é agnóstica de transporte. O servidor de referência é somente stdio.
Modelo de segurança
- Trust-on-First-Use é o padrão. Na primeira vez que você verifica um servidor, a chave pública dele é fixada em
~/.mcp-attest/trust.json(substituível por:MCP_ATTEST_TRUST_FILE). Verificações subsequentes rejeitam qualquer chave nova para o mesmo nome de servidor comTRUST_PIN_MISMATCH. Isso captura o vetor de atualização maliciosa no estilo Cursor. - Nenhuma lista de chaves confiáveis embutida. Este pacote não atua como um guardião. Se você quiser uma garantia mais forte, opte por
--sigstorepara fazer referência cruzada da impressão digital da chave pública com o log de transparência Rekor da Sigstore. - Sanitizador de argumentos com negação por padrão.
shellSafeStringbloqueia todo metacaractere de shell ASCII, NUL, CR, LF, VT, FF, NEL, caracteres de largura zero, BOM, overrides RTL/LTR, isoladores Trojan-Source e confundíveis latinos de largura total. O comportamento de lista de permissões exige os tipos de regra explícitosregex/enum/prefix/literal. - Regras
regexseguras contra ReDoS. O padrão de uma regraregexé assinado pelo autor, mas o valor do argumento é controlado pelo atacante. O sanitizador detecta estaticamente padrões propensos a backtracking (quantificadores ilimitados aninhados como(a+)+) e se recusa a executá-los, de modo que um único argumento elaborado não pode congelar o caminho quente do spawn. As regrasregextambém possuem um limite de entradamaxLength(padrão 4096). - Regras
prefixseguras contra travessia. As regrasprefixrejeitam componentes de caminho..por padrão (denyTraversal: true, incluindo a forma codificada%2e%2e), portanto/safe/../../etc/passwdé bloqueado mesmo satisfazendoprefix: "/safe/". - Verificar-e-atestar.
attestSpawnVerifiedverifica a assinatura do manifesto antes de atestar o spawn em uma única chamada à prova de falhas — use-a em vez deattestSpawnStrict, a menos que você tenha medido a verificação Ed25519 por spawn fora de um loop genuinamente quente. - JSON canônico é a superfície assinada. A re-serialização não pode alterar os bytes assinados.
O que este pacote NÃO faz (fora do escopo):
- Isolar em sandbox ou conteinerizar o processo do servidor.
- Endurecimento do fluxo OAuth (build separado
mcp-oauth-shield). - Controle de egresso de rede.
- Correção automática de servidores existentes.
Testes
npm install
npm run typecheck
npm test
O corpus de testes inclui fixtures de replay de CVE (packages/lib/tests/fixtures/cve-2025-69256-payloads.json, cve-2025-61591-payloads.json). O build é uma verificação de regressão: todo payload deve ser bloqueado.
Distribuição
- Publicação npm via GitHub Actions OIDC com
--provenance. - Servidor de referência submetido ao mcp.so e ao FastMCP Directory.
- Biblioteca publicada separadamente como
mcp-server-attestation.
Sobre a StudioMeyer
StudioMeyer é um estúdio de IA e design baseado em Palma de Mallorca, trabalhando com clientes no mundo todo. Construímos sites personalizados e infraestrutura de IA para pequenas e médias empresas. Stack de produção no Claude Agent SDK, MCP e n8n, com Sentry, Langfuse e LangGraph para observabilidade e uma camada de guarda interna.
Licença
MIT, Direitos autorais 2026 Matthias Meyer (StudioMeyer). Consulte LICENSE.