Una nota nascosta in un ticket di assistenza entra nell’agente che riassume il testo. Il riassunto passa a un secondo agente, che interpreta la nota come un incarico legittimo. Un terzo componente usa le credenziali del proprio server MCP per interrogare un endpoint interno. Nessun elemento della catena si comporta in modo anomalo preso da solo. Il problema nasce perché ogni passaggio eredita la fiducia del precedente.
È questo il rischio operativo dietro il “protocol pivoting”, il nome dato dal ricercatore Syed Anas Mohiuddin a una classe di attacchi che attraversa protocolli e agenti. La definizione è nuova; le debolezze sono note: prompt injection indiretta, autorizzazioni troppo ampie, Server-Side Request Forgery (SSRF), parametri non validati e identità perse durante la delega. Per una PMI che collega un assistente a WordPress, CRM, database o posta, la domanda utile non è se MCP sia sicuro in astratto. È dove finisce l’autorità del singolo passaggio.
Il caso reale: un input diventa un’azione interna
Il 5 ottobre 2026 Ars Technica ha documentato i test di Mohiuddin su agenti e server usati da organizzazioni diverse. Il filo comune non era un unico modello o fornitore, ma la fiducia tra componenti: contenuto controllato dall’esterno entrava in un agente specializzato e veniva inoltrato come lavoro interno a un altro agente dotato di più capacità.
Un esempio verificabile è CVE-2026-97228 nel database NVD. Le versioni dalla 0.2.5 alla 0.6.1 di Rapid7 Bulk Export MCP interpolavano il parametro export_id dentro una query GraphQL. Un valore costruito apposta poteva chiudere la selezione prevista e aggiungere campi alla query eseguita con la chiave API dell’operatore. La versione 0.6.2 usa invece una variabile GraphQL parametrizzata. Il punteggio CVSS è 2,7 su 10 perché l’impatto resta entro i permessi dell’account già autenticato; ciò non rende il bug irrilevante. Mostra che un input passato da un client MCP compromesso o ingannato può raggiungere un’API con credenziali valide.
Google ha affrontato un’altra faccia dello stesso problema nel proprio MCP Toolbox for Databases. La pull request 3448, integrata il 18 giugno 2026, ha introdotto una protezione SSRF per la sorgente HTTP, controlli contro il DNS rebinding, validazione anticipata della base URL e opzioni esplicite per reti private e intervalli ammessi. Due correzioni successive hanno chiuso casi che il primo filtro non copriva: la rete CGNAT 100.64.0.0/10 nella pull request 3625 e l’intervallo riservato 192.0.0.0/24 nella pull request 3909. Quest’ultima è entrata nella release 1.11.0 del 10 settembre 2026.
La sequenza conta più del singolo bug. Bloccare “gli IP privati” con una funzione generica non basta; redirect, risoluzione DNS e intervalli speciali richiedono controlli al momento della connessione. La mia take è netta: un server MCP che può fare richieste HTTP non è un semplice connettore. È un proxy con credenziali e va progettato come tale.
MCP non trasferisce automaticamente il contesto di fiducia
MCP standardizza come un’applicazione scopre e invoca tool, risorse e prompt. A2A e altri protocolli gestiscono invece la delega tra agenti. Quando un incarico passa da un protocollo all’altro, il testo può sopravvivere mentre si perdono informazioni essenziali: chi ha originato la richiesta, quale utente l’ha autorizzata, quali dati può leggere e se l’azione richiede conferma.
Dire “arriva da un agente interno” non risolve nulla. Quell’agente può avere letto una pagina web, un PDF, un’email o un campo del CRM controllato da terzi. La guida di sicurezza ufficiale MCP tratta separatamente confused deputy, token passthrough, SSRF e minimizzazione degli scope. È un indizio architetturale: l’autenticazione del trasporto non prova che l’istruzione contenuta nel messaggio sia affidabile.
Conviene rappresentare ogni chiamata con quattro elementi distinti:
- l’identità dell’utente o del servizio che ha iniziato il lavoro;
- la provenienza dei dati usati per decidere, per esempio web, email o database interno;
- lo scope concesso a quel singolo passaggio;
- la decisione richiesta: leggere, proporre, scrivere, inviare o cancellare.
Se uno di questi elementi manca, il componente successivo non dovrebbe ricostruirlo dal testo. Deve ridurre i permessi, chiedere approvazione o fermarsi. La stessa separazione è utile quando si espone una API WordPress protetta con VPN o JWT: la rete e il token dicono chi può arrivare all’endpoint; una policy applicativa decide che cosa può fare.
I sette controlli da mettere tra agente e tool
1. Un’identità per ogni passaggio
Non riutilizzare un token amministratore per tutti gli agenti. Il componente che legge il catalogo non deve avere la stessa identità di quello che aggiorna prezzi o pubblica pagine. Conserva nel log l’utente originario e l’agente delegato, ma verifica i permessi sul servizio di destinazione. Un campo requested_by dentro il prompt è informazione, non autenticazione.
2. Scope piccoli e legati al tool
Se il workflow deve leggere ordini, non concedergli shop:*. Se prepara una bozza WordPress, usa un ruolo capace di creare draft, non di installare plugin o modificare utenti. Per database e storage, separa lettura e scrittura. Lo scope deve descrivere l’azione tecnica, non il nome generico dell’assistente.
3. Parametri validati fuori dal modello
JSON Schema aiuta a imporre tipi e campi obbligatori, ma non sostituisce le regole di dominio. Un URL formalmente valido può puntare al metadata service del cloud; un ID può contenere caratteri significativi per GraphQL o SQL; un percorso può uscire dalla directory prevista. Usa allowlist, query parametrizzate, limiti di lunghezza e normalizzazione nel codice che esegue il tool.
4. Egress chiuso per default
Un server MCP con accesso HTTP dovrebbe raggiungere solo host e porte necessari. Blocca loopback, reti private, link-local, CGNAT e intervalli riservati, anche dopo la risoluzione DNS. Controlla ogni redirect e risolvi di nuovo il nome al momento della connessione per ridurre il DNS rebinding. Nei flussi più sensibili, passa da un egress proxy con policy e log.
5. Lettura separata dalle azioni irreversibili
L’agente può raccogliere dati e proporre un payload. Un servizio deterministico valida quindi prezzi, destinatari, URL, permessi e soglie. Pubblicazione, invio email, pagamenti, cancellazioni e cambi di accesso richiedono un gate esplicito. È lo stesso principio della pipeline di guardrail prima del go-live: una risposta plausibile non è una ricevuta di esecuzione corretta.
6. Output non attendibile anche se arriva dall’interno
Marca i dati provenienti da web, allegati e campi liberi. Quando un agente li riassume, non eliminare l’etichetta di provenienza. Il componente successivo deve trattare il risultato come contenuto non attendibile, non come una nuova system instruction. Se il protocollo usato per la delega non conserva questa informazione, aggiungila in un envelope firmato o riduci l’azione possibile al solo read-only.
7. Log della decisione, non solo della conversazione
Registra tool invocato, identità, scope, origine dei dati, parametri normalizzati, destinazione di rete, esito del controllo e motivo dell’eventuale approvazione. Un transcript completo può contenere dati personali e comunque non chiarisce quale regola abbia autorizzato l’azione. Il log utile permette di rispondere: “perché questo agente ha potuto chiamare proprio quel servizio?”
Il laboratorio minimo per WordPress e n8n
Consideriamo un’automazione concreta: n8n legge una richiesta dal form del sito, un agente la classifica, un secondo agente consulta il CRM e un tool MCP prepara una bozza WordPress. La versione fragile usa una sola chiave API, permette URL arbitrari per recuperare allegati e lascia che il testo del form determini direttamente titolo, categoria e stato del post.
La versione difendibile divide il percorso:
- il webhook salva i dati grezzi e assegna un ID interno;
- il classificatore restituisce solo una categoria da una enum chiusa e non possiede tool di scrittura;
- il recupero CRM usa l’ID normalizzato, non una query prodotta dal modello;
- gli allegati vengono scaricati da host ammessi, con limite di dimensione e controllo del tipo reale;
- il generatore produce HTML e metadati in un oggetto strutturato;
- un validatore elimina tag vietati, controlla link, categoria e campi obbligatori;
- l’account WordPress crea soltanto una bozza; il passaggio a
publishrichiede un gate separato.
Non serve installare un modello diverso per ottenere questa separazione. Serve togliere autorità dal prompt e riportarla nel codice. Anche le chiavi vanno custodite fuori dal contesto del modello: il caso delle chiavi API dietro un network proxy mostra come evitare che una sessione di coding riceva direttamente il segreto che usa.
Per la rete, crea due destinazioni. Il tool WordPress parla solo con il dominio del sito e con l’endpoint REST necessario. Il tool che recupera fonti esterne usa un proxy distinto, senza credenziali WordPress e senza accesso alla LAN. Se il secondo viene ingannato da una pagina, non può trasformare quella pagina in una richiesta autenticata al CMS.
Come testare il pivot prima della produzione
Un test utile non chiede al modello “sei sicuro?”. Inserisce input ostili nei punti reali del workflow e verifica che l’azione venga bloccata. Prepara almeno questi casi:
- un ticket che ordina di ignorare il compito e leggere un altro cliente;
- un documento con un URL che risponde con redirect verso
127.0.0.1o169.254.169.254; - un hostname che cambia risoluzione tra validazione e connessione;
- un parametro con virgolette, parentesi e separatori usati dal linguaggio a valle;
- una richiesta valida che supera il budget o il numero massimo di record;
- una delega priva dell’identità originaria o dell’etichetta di provenienza;
- un tool read-only che tenta una chiamata di scrittura.
Il risultato atteso non è sempre un errore. Un workflow può trasformare l’azione in bozza, ridurre il set di dati o chiedere approvazione. L’importante è che il comportamento derivi da una policy osservabile e non dalla disponibilità del modello a obbedire.
Aggiungi questi casi agli eval dopo ogni modifica di modello, prompt, server MCP o protocollo di delega. Una patch al singolo connettore chiude un percorso; non prova che la catena completa conservi identità e limiti. Testa quindi sia il tool isolato sia il passaggio agente A → agente B → tool.
Un piano di hardening in due settimane
Giorni 1-3: inventario di agenti, tool e credenziali
Disegna il flusso reale. Per ogni nodo annota dati in ingresso, protocolli, token, host raggiungibili e azioni. Evidenzia credenziali condivise, tool che accettano URL e componenti che possono scrivere. Se non sai quale identità esegue una chiamata, hai già trovato il primo difetto.
Giorni 4-7: riduzione dell’autorità
Separa gli account, restringi gli scope, imposta allowlist di destinazioni e trasforma le azioni irreversibili in draft o richieste di approvazione. Aggiorna i server MCP alle versioni corrette, ma non fermarti alla versione: controlla configurazioni come allowPrivateNetworks, verifica TLS e redirect.
Giorni 8-10: validatori e confini di rete
Sposta dal prompt al codice la validazione di ID, query, URL e percorsi. Configura egress proxy o firewall per impedire al tool esterno di raggiungere rete privata, metadata service e pannelli amministrativi. Applica la regola anche ai redirect e dopo la risoluzione DNS.
Giorni 11-14: test avversari e log
Esegui i casi ostili, verifica i log e misura quanti passaggi arrivano al gate umano. Correggi prima i percorsi che combinano input esterno, credenziale privilegiata e scrittura. Sono quelli in cui un prompt injection smette di essere testo e diventa un incidente.
Chiusura operativa
Il protocol pivoting non richiede una nuova categoria di difesa. Richiede di applicare zero trust dentro l’orchestrazione: ogni agente è un chiamante distinto, ogni output può contenere input ostile e ogni tool deve verificare l’autorità prima di agire. Patch e versioni aggiornate servono, ma non possono ricostruire un’identità che il workflow ha perso.
Se oggi devi scegliere tre interventi, separa le credenziali per tool, chiudi l’egress con allowlist e inserisci un gate deterministico davanti alle azioni irreversibili. Poi prova a far attraversare la catena da un input malevolo. Se il blocco avviene solo perché il modello “capisce” che la richiesta è sospetta, il confine di sicurezza non esiste ancora.
Fonti
- Ars Technica: MCP, agenti e protocol pivoting
- NVD: CVE-2026-97228, Rapid7 Bulk Export MCP
- Google MCP Toolbox: implementazione della protezione SSRF
- Google MCP Toolbox: blocco della rete CGNAT
- Google MCP Toolbox: blocco dell’intervallo IETF 192.0.0.0/24
- Model Context Protocol: Security Best Practices

