
Segurança MCP: O que Aprendi ao Proteger Meu Servidor MCP Após 95 Interrupções de Produção
Segurança MCP: O Que Aprendi ao Proteger Meu Servidor MCP Após 95 Interrupções na Produção
Quando comecei a construir o Papers, meu servidor de base de conhecimento MCP, há três anos, pensei na segurança como algo que "simplesmente acontece" se você seguir as regras básicas. Mantenha suas dependências atualizadas, não codifique segredos, use HTTPS — é isso, certo?
Após 95 interrupções na produção, mais de 1800 horas de desenvolvimento e inúmeros momentos de confusão relacionados à segurança, posso te dizer: a segurança MCP é diferente. Não é a segurança padrão de API REST. A natureza do Protocolo de Contexto de Modelo cria novas superfícies de ataque para as quais a maioria das orientações de segurança tradicionais não está preparada.
Deixe-me te mostrar o que aprendi da maneira mais difícil.
O Modelo de Ameaça Diferente do MCP
Primeiro, vamos deixar isso claro: MCP não é REST. Em uma API REST tradicional, você sabe exatamente quem está chamando o quê, quando e por quê. O cliente é uma aplicação conhecida, o usuário está autenticado desde o início e as solicitações seguem padrões previsíveis.
O MCP muda tudo:
- O cliente é um LLM — isso significa que o LLM pode alucinar chamadas de ferramentas, parâmetros, até mesmo endpoints inteiros que não existem. Não é um humano clicando em um botão; é um modelo "adivinhando" o que chamar com base no contexto.
- Invocação indireta — o usuário não chama suas ferramentas diretamente. O usuário fala com o LLM, o LLM fala com seu servidor MCP. Você não recebe validação direta de entrada do usuário de uma interface de usuário.
- Descoberta dinâmica de ferramentas — cada cliente busca a lista de ferramentas na inicialização, então mudanças no esquema quebram clientes de maneiras imprevisíveis. Mas isso também significa que clientes maliciosos podem sondar seu servidor em busca de ferramentas ocultas.
- Clientes de terceiros — se você abrir seu servidor MCP para múltiplos clientes de IA (como Claude Desktop, ChatGPT, OpenClaw, etc.), cada cliente tem seu próprio modelo de segurança, sua própria autenticação, sua própria maneira de lidar com entradas.
Seu modelo de ameaça não é mais "um usuário malicioso tentando invadir". É "um LLM bem-intencionado cometendo erros acidentais que podem derrubar seu servidor, vazar dados ou abrir você para abusos".
Não me entenda mal — atores maliciosos ainda são uma preocupação. Mas a maioria das minhas interrupções relacionadas à segurança veio de usos acidentais por LLMs perfeitamente legítimos.
Lição 1: O Gerenciamento de Chaves de API É Mais Complicado do Que Você Pensa
A maioria dos servidores MCP usa chaves de API para autenticação. Isso faz sentido — é simples, funciona com todos os clientes. Mas como você gerencia essas chaves importa mais do que você pensa.
Aqui está o que me pegou no início: Eu permiti que as chaves de API fossem passadas em três lugares diferentes porque diferentes clientes esperam lugares diferentes. Alguns clientes enviam no cabeçalho Authorization: Bearer. Alguns enviam como um parâmetro de consulta. Alguns enviam no corpo JSON.
Eu pensei "suportar os três facilita para os clientes" — isso é uma coisa boa, certo?
Errado.
O problema? Parâmetros de consulta são registrados em todos os lugares. Todo proxy, todo servidor, todo CDN registra a URL. Sua chave de API acaba em arquivos de log, painéis de monitoramento, histórico do navegador, em todo lugar. Se você estiver usando um serviço de hospedagem de terceiros, isso significa que sua chave de API é potencialmente visível para quem tiver acesso a esses logs.
O que eu faço agora:
- Sempre prefira autenticação por cabeçalho (
Authorization: Bearer <key>) - Se você precisar suportar parâmetros de consulta, faça hash da chave nos logs e não a armazene permanentemente
- Nunca aceite chaves de API no corpo da solicitação JSON se puder evitar — isso pode acabar em logs de depuração mais facilmente
- Gire as chaves regularmente — mesmo que nada esteja errado, a rotação é uma boa prática
Mas aqui está outra reviravolta específica do MCP: clientes diferentes precisam de chaves diferentes. Eu costumava ter uma chave que todos os clientes usavam. Isso tornava impossível:
- Revogar o acesso de um cliente problemático sem quebrar todos os outros
- Rastrear qual cliente está fazendo quais chamadas
- Limitar a taxa com base na identidade do cliente
Agora eu emito uma chave de API diferente para cada instalação de cliente. É uma tabela extra no banco de dados, adiciona quase nenhuma complexidade e resolveu tantos problemas.
Lição 2: Valide Tudo Duas Vezes — Porque LLMs Alucinam
Já falamos sobre validação em um post anterior, mas a validação de segurança é diferente da validação de entrada regular.
LLMs alucinam nomes de parâmetros. Eles alucinam tipos de parâmetros. Eles alucinam nomes de ferramentas que não existem. Eles até alucinam ferramentas inteiras que você nunca criou.
Isso não é apenas um problema de usabilidade — é um problema de segurança.
Considere isso: você tem uma ferramenta que pesquisa sua base de conhecimento. Ela aceita um parâmetro query que é uma string. Um LLM alucina query como um array de objetos em vez de uma string. Se você não estiver validando corretamente, o que acontece?
- Pode travar seu analisador JSON
- Pode acionar caminhos de código inesperados
- Pode causar recursão infinita em estruturas profundamente aninhadas
- Pode contornar seus limites de tamanho de entrada
A lista de verificação de validação de segurança MCP que uso agora:
O nome da ferramenta deve existir — antes de fazer qualquer coisa, verifique se a ferramenta solicitada está realmente na sua lista de descoberta. Rejeite imediatamente se não estiver. Não deixe cair na sua camada de roteamento.
A contagem de parâmetros deve corresponder — LLMs adoram adicionar parâmetros extras que não estão no esquema. Rejeite a chamada se houver parâmetros que não estão definidos. Algumas pessoas dizem "apenas ignore parâmetros extras", mas eu discordo — um parâmetro extra pode ser uma tentativa de injeção, ou pode significar que o LLM está confuso sobre qual ferramenta está chamando. Melhor falhar rapidamente e deixar o LLM corrigir a si mesmo.
Os tipos de parâmetros devem corresponder exatamente — não coerça tipos a menos que você absolutamente tenha que. Se o esquema diz que é uma string, deve ser uma string. Se é um número, deve ser um número. Deixe o LLM corrigir seus próprios erros.
Imponha limites de tamanho em tudo — cada string, cada array, cada objeto. LLMs podem gerar entradas gigantescas acidentalmente. Uma vez, tive um LLM gerando um parâmetro de prompt de 10MB porque continuava se repetindo. Defina tamanhos máximos razoáveis e rejeite qualquer coisa maior.
Sanitize caminhos se você estiver lidando com acesso ao sistema de arquivos — isso parece óbvio, mas você ficaria surpreso com quantas ferramentas MCP que trabalham com arquivos esquecem disso. O LLM pode alucinar um caminho como
../../secret/keyse se você não sanitizar, você acabou de dar acesso.
Lição 3: O Problema de Pré-vôo do CORS Que Me Pegou Duas Vezes
Espere — CORS é uma coisa de navegador, como isso é um problema de segurança?
Eu pensei a mesma coisa. Então eu fui mordido duas vezes.
Aqui está o cenário: você está executando seu servidor MCP em api.seudominio.com, e seu frontend está em seudominio.com. Você configurou o CORS corretamente, permite credenciais, toda a coisa. Tudo funciona em desenvolvimento.
Mas o MCP faz solicitações OPTIONS de pré-vôo constantemente. Cada chamada de ferramenta pode acionar um pré-vôo, dependendo do cliente. E aqui está a coisa: as solicitações de pré-vôo não enviam credenciais de autenticação por padrão.
Se seu filtro CORS não permitir solicitações OPTIONS não autenticadas, o pré-vôo falha, o navegador bloqueia a solicitação e o cliente recebe um erro CORS vago. Mas isso é apenas disponibilidade, certo? Não é segurança.
Errado novamente.
Quando você permite OPTIONS não autenticadas, precisa ter certeza:
- Que realmente não realiza nenhuma ação autenticada
Empresas brasileiras que utilizam o MCP devem estar cientes das novas superfícies de ataque que surgem com a integração de LLMs. A gestão de chaves de API e a validação de entradas são cruciais para evitar falhas de segurança. Adotar práticas de segurança adaptadas ao MCP pode prevenir interrupções e vazamentos de dados.

