Passa al contenuto principale

Mettere in sicurezza i server MCP: OAuth, audience binding e il deputato confuso

Avanzato
What you'll learn
  • Capire perché un server MCP remoto (HTTP) è un resource server OAuth 2.1, non un semplice endpoint con API key
  • Ripercorrere l'handshake di discovery: 401 → Protected Resource Metadata → Authorization Server Metadata → token
  • Spiegare l'audience binding del token (RFC 8707) e perché impedisce che il token di un servizio funzioni su un altro
  • Riconoscere la trappola del deputato confuso e l'unica regola che la chiude: non inoltrare mai il token del client a un'API upstream
  • Applicare una breve checklist di hardening prima di esporre un server MCP a Internet

MCP è passato da novità al modo predefinito con cui gli agent raggiungono i tool — il che significa che i server MCP ora si trovano davanti a dati reali e azioni reali. Un server locale che avvii su STDIO si fida del suo ambiente: legge le credenziali dalle variabili d'ambiente e non c'è alcun confine di rete da difendere. Nel momento in cui rendi lo stesso server remoto (HTTP), chiunque possa raggiungere l'URL può provare a chiamarlo. Questo lo trasforma in un problema di autorizzazione, e la spec MCP risponde con OAuth 2.1 — non con uno schema ad hoc a base di API key.

Questa pagina riguarda il caso remoto. Se il tuo server è solo STDIO, la spec dice esplicitamente di non seguire il flusso OAuth — prendi le credenziali dall'ambiente e prosegui.

I tre ruoli

OAuth divide il problema fra tre parti. MCP vi si mappa in modo pulito:

Chi è chi in un flusso OAuth di MCP
Premi Invio o Spazio per girare la carta. Usa le frecce sinistra e destra per spostarti tra le carte.Termine mostrato.
1 / 3

Lo spostamento mentale chiave: il server MCP non gestisce mai il login da sé. Valida soltanto token emessi da qualcun altro. È questa separazione a permetterti di mettere un identity provider pronto all'uso davanti a un server che hai scritto tu.

L'handshake di discovery

Un client non dovrebbe dover essere pre-configurato con l'informazione di dove autenticarsi. MCP rende la discovery automatica, guidata da un 401:

Guided walkthrough1 of 6
  1. La primissima richiesta parte nuda. Il server la rifiuta con HTTP 401 Unauthorized e un header WWW-Authenticate che punta al suo URL di resource-metadata.

Nota che non c'è alcuna configurazione di auth hardcoded dal lato client — il 401 fa da bootstrap per tutto. È esattamente questo il punto: un agent può connettersi a un server mai visto prima e capire come autenticarsi.

Audience binding: la regola portante

Ecco la modalità di guasto che l'audience binding esiste per prevenire. Supponi che un utente abbia un token emesso per calendar.example.com. Un server MCP malevolo (o semplicemente sciatto) su evil.example.com induce il client a inviare quel token a sé. Se evil lo accetta, può a sua volta chiamare l'API del calendario come l'utente. Il token di un servizio ha funzionato su un altro. Il confine di sicurezza di OAuth è appena crollato.

La correzione sono i Resource Indicators (RFC 8707):

Guided walkthrough1 of 3
  1. Sia nella richiesta di autorizzazione sia in quella di token, il client DEVE includere un parametro resource impostato all'URI canonico del server MCP che intende chiamare — es. resource=https://mcp.example.com. Lo invia anche se non è certo che l'AS lo supporti.

Parametro resource nella richiesta di autorizzazione (URL-encoded)

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

Gli URI canonici sono rigidi: https://mcp.example.com e https://mcp.example.com:8443/mcp sono validi; mcp.example.com (senza schema) e https://mcp.example.com#frag (frammento) non lo sono. Preferisci la forma senza slash finale per l'interoperabilità.

Il deputato confuso: non inoltrare mai il token

Questo è l'errore che trasforma un server MCP ben intenzionato nel proxy di un attaccante. È lo stesso problema del deputato confuso della sicurezza degli agent, ridotto a un'unica regola concreta.

Un server MCP spesso ha bisogno di chiamare un'API upstream (GitHub, un servizio di database, un altro SaaS). La tentazione è prendere il token che il client ti ha passato e inoltrarlo upstream. Non farlo. La spec è netta: il server MCP NON DEVE inoltrare il token ricevuto dal client.

Perché è pericoloso: il token del client è stato emesso con il tuo server come audience. Se lo inoltri, l'API upstream potrebbe fidarsene come se venisse da te, o presumere che tu l'abbia già validato — e ora un token pensato per un solo hop sta operando a due hop di distanza, fuori dal modello di consenso di chiunque.

Watch out
  • Se il tuo server MCP chiama un'API upstream, agisce come un client OAuth SEPARATO verso quell'API e ottiene il PROPRIO token dall'authorization server upstream. Due token indipendenti, due audience indipendenti. Il token del client si ferma alla tua porta.

Una checklist di hardening pre-volo

Prima che un server MCP remoto tocchi Internet pubblico:

Guided walkthrough1 of 7
  1. Tutti gli endpoint dell'AS DEVONO essere HTTPS. I redirect URI DEVONO essere HTTPS o localhost — nient'altro.

Mettiti alla prova

Mettiti alla prova

0/4
  1. Un server MCP remoto riceve una richiesta senza access token. Cosa impone la spec di fare per prima cosa?
  2. Da cosa protegge l'audience binding del token (RFC 8707)?
  3. Il tuo server MCP deve chiamare un'API GitHub upstream. Cosa dovrebbe fare con l'access token che il client gli ha inviato?
  4. Per un server MCP STDIO (locale), come dice la spec di gestire le credenziali?

Fonti e approfondimenti