Pular para o conteúdo principal

Protegendo Servidores MCP: OAuth, Vinculação de Audiência e o Delegado Confuso

Avançado
What you'll learn
  • Entender por que um servidor MCP remoto (HTTP) é um servidor de recursos OAuth 2.1, e não apenas um endpoint com chave de API
  • Rastrear o handshake de descoberta: 401 → Protected Resource Metadata → Authorization Server Metadata → token
  • Explicar a vinculação de audiência do token (RFC 8707) e por que ela impede que o token de um serviço funcione em outro
  • Nomear a armadilha do delegado confuso e a única regra que a fecha: nunca repasse o token de um cliente para uma API upstream
  • Aplicar uma breve checklist de hardening antes de expor um servidor MCP à internet

MCP deixou de ser novidade para se tornar a forma padrão de os agentes acessarem ferramentas — o que significa que os servidores MCP agora ficam na frente de dados reais e ações reais. Um servidor local que você inicia via STDIO confia em seu ambiente: ele lê credenciais de variáveis de ambiente e não há fronteira de rede a defender. No momento em que você torna esse mesmo servidor remoto (HTTP), qualquer um que consiga alcançar a URL pode tentar chamá-lo. Isso o transforma em um problema de autorização, e a especificação MCP responde com OAuth 2.1 — e não com um esquema de chave de API improvisado.

Esta página trata do caso remoto. Se o seu servidor for apenas STDIO, a especificação diz explicitamente para não seguir o fluxo OAuth — obtenha as credenciais do ambiente e siga em frente.

Os três papéis

O OAuth divide o problema entre três partes. O MCP se mapeia nelas de forma limpa:

Quem é quem em um fluxo OAuth de MCP
Pressione Enter ou Espaço para virar o cartão. Use as setas esquerda e direita para navegar entre os cartões.Termo exibido.
1 / 3

A mudança mental principal: o servidor MCP nunca lida com o login em si. Ele apenas valida tokens que outra pessoa emitiu. Essa separação é o que permite colocar um provedor de identidade pronto na frente de um servidor que você escreveu.

O handshake de descoberta

Um cliente não deveria precisar ser pré-configurado com o local onde se autenticar. O MCP torna a descoberta automática, guiada por um 401:

Guided walkthrough1 of 6
  1. A primeira requisição sai sem nada. O servidor a rejeita com HTTP 401 Unauthorized e um cabeçalho WWW-Authenticate apontando para sua URL de resource-metadata.

Repare que não há nenhuma configuração de autenticação hardcoded do lado do cliente — o 401 inicializa tudo. Esse é justamente o objetivo: um agente pode se conectar a um servidor que nunca viu e descobrir como se autenticar.

Vinculação de audiência: a regra que sustenta tudo

Aqui está o modo de falha que a vinculação de audiência existe para evitar. Digamos que um usuário tenha um token emitido para calendar.example.com. Um servidor MCP malicioso (ou apenas desleixado) em evil.example.com engana o cliente para que envie aquele token a ele. Se evil o aceitar, ele agora pode se virar e chamar a API do calendário como se fosse o usuário. O token de um serviço funcionou em outro. A fronteira de segurança do OAuth acabou de desmoronar.

A correção são os Resource Indicators (RFC 8707):

Guided walkthrough1 of 3
  1. Tanto na requisição de autorização quanto na requisição de token, o cliente DEVE incluir um parâmetro resource definido com a URI canônica do servidor MCP que ele pretende chamar — por exemplo, resource=https://mcp.example.com. Ele envia isso mesmo sem ter certeza de que o AS o suporta.

Parâmetro resource na requisição de autorização (URL-encoded)

&resource=https%3A%2F%2Fmcp.example.com

As URIs canônicas são rígidas: https://mcp.example.com e https://mcp.example.com:8443/mcp são válidas; mcp.example.com (sem esquema) e https://mcp.example.com#frag (fragmento) não são. Prefira a forma sem barra final para interoperabilidade.

O delegado confuso: nunca repasse o token

Este é o erro que transforma um servidor MCP bem-intencionado no proxy de um atacante. É o mesmo problema do delegado confuso da segurança de agentes, afiado em uma única regra concreta.

Um servidor MCP muitas vezes precisa chamar uma API upstream (GitHub, um serviço de banco de dados, outro SaaS). A tentação é pegar o token que o cliente lhe entregou e encaminhá-lo para o upstream. Não faça isso. A especificação é direta: o servidor MCP NÃO DEVE repassar o token que recebeu do cliente.

Por que é perigoso: o token do cliente foi emitido tendo o seu servidor como audiência. Se você o encaminha, a API upstream pode confiar nele como se tivesse vindo de você, ou presumir que você já o validou — e agora um token com escopo para um salto está fazendo trabalho a dois saltos de distância, fora do modelo de consentimento de qualquer um.

Watch out
  • Se o seu servidor MCP chama uma API upstream, ele age como um cliente OAuth SEPARADO para essa API e obtém seu PRÓPRIO token do servidor de autorização upstream. Dois tokens independentes, duas audiências independentes. O token do cliente para na sua porta.

Uma checklist de hardening de pré-voo

Antes que um servidor MCP remoto toque a internet pública:

Guided walkthrough1 of 7
  1. Todos os endpoints do AS DEVEM ser HTTPS. As redirect URIs DEVEM ser HTTPS ou localhost — nada mais.

Teste você mesmo

Teste você mesmo

0/4
  1. Um servidor MCP remoto recebe uma requisição sem token de acesso. O que a especificação exige que ele faça primeiro?
  2. Contra o que a vinculação de audiência do token (RFC 8707) protege?
  3. Seu servidor MCP precisa chamar uma API upstream do GitHub. O que ele deve fazer com o token de acesso que o cliente lhe enviou?
  4. Para um servidor MCP STDIO (local), como a especificação diz que as credenciais devem ser tratadas?

Fontes e leitura adicional