Come verificare la sicurezza MCP in una pull request?
Un server MCP nel repository gira sulla macchina di chiunque lo approvi. Dalla documentazione di cinque strumenti, una checklist.
In sintesi. MCP (Model Context Protocol) è un protocollo aperto con cui gli agenti di programmazione si collegano a tool esterni. Un server MCP entra nel repository come un piccolo file JSON o TOML e viene committato insieme al codice. Il 18 ottobre 2026 abbiamo letto nella documentazione di ogni strumento quando Claude Code, Cursor, Codex, Gemini CLI e GitHub Copilot leggono quel file e che cosa chiedono prima di avviare il server. Partendo dalla specifica MCP, dalla lista di OWASP e dai record della NVD, abbiamo preparato una checklist per una pull request che modifica quel file. Il 28 ottobre 2026 abbiamo aggiunto Antigravity CLI di Google.
- Un server MCP è un programma, non un’impostazione. La riga
commanddel file gira sulla macchina di ogni persona che approva il server, con i suoi permessi. La stessa specifica MCP definisce i tool come esecuzione di codice arbitrario («arbitrary code execution»). - L’approvazione vede solo la prima versione del server. Claude Code salva l’approvazione con il nome del server. In un’area di lavoro attendibile, VS Code può avviare il server senza chiedere di nuovo, anche dopo che la sua configurazione è cambiata. Nelle esecuzioni
-pdi Claude Code la domanda non arriva proprio. - Il modello legge la descrizione di un tool come un’istruzione. Il tool poisoning nasconde in quella descrizione un’istruzione che l’utente non vede. In MCPTox, il successo medio degli attacchi su 20 configurazioni di modelli del 2025 è stato del 36,5%.
- Ogni modifica successiva la leggi nella pull request. La nostra checklist ha 9 domande: il comando, la versione, un server che cambia con lo stesso nome, le approvazioni che arrivano con la pull request, i segreti, i comandi di supporto, i tool che leggono testo esterno, il codice del server stesso e la CI.
Come entra un server MCP in un repository?
Questo articolo guarda la configurazione che una pull request porta per l’agente di programmazione. Nell’articolo sugli hook abbiamo parlato dei comandi che l’agente esegue da solo in momenti precisi, e nell’articolo su come esaminare il codice scritto dall’IA del codice che l’agente scrive. Qui l’argomento è il file che dà all’agente un nuovo tool.
MCP (Model Context Protocol) è, secondo la definizione della specifica stessa, un protocollo aperto che collega le applicazioni di IA a fonti di dati e tool esterni. Da una parte c’è l’agente, dall’altra un server MCP. Il server definisce i tool che il modello può chiamare: leggere una issue, aprire un browser, interrogare un database. Al 18 ottobre 2026, la revisione più recente della specifica è datata 2026-07-28.
Il più delle volte il server è un programma che gira sulla tua macchina. Lo strumento di programmazione lo avvia con le righe command e args del file di configurazione e ci parla attraverso lo standard input e lo standard output del programma; la specifica lo chiama stdio. Per un server remoto, nel file c’è un indirizzo (url) al posto di un comando. Questo file viene committato con il codice: la documentazione di Claude Code consiglia di mettere .mcp.json sotto controllo di versione, così tutto il team usa gli stessi tool. Ogni strumento guarda un file diverso:
| Strumento | File nel repository | Nota |
|---|---|---|
| Claude Code | .mcp.json (root del progetto) | Le tue approvazioni vengono scritte in .claude/settings.local.json |
| Cursor | .cursor/mcp.json | File utente: ~/.cursor/mcp.json |
| Codex | .codex/config.toml | Letto solo nei progetti attendibili |
| Gemini CLI | .gemini/settings.json | File utente: ~/.gemini/settings.json |
| GitHub Copilot | CLI: .mcp.json, .github/mcp.json. VS Code: .vscode/mcp.json, il .mcp.json nella root | Nessun file per l’agente cloud: la configurazione sta nelle impostazioni del repository su GitHub.com |
Fonte: la documentazione MCP di ogni strumento, 18 ottobre 2026. Copilot CLI non legge il file .vscode/mcp.json di VS Code. In Antigravity CLI il file nel repository è .agents/mcp_config.json.
La specifica MCP dice in una frase che cosa significa: «Tools represent arbitrary code execution and must be treated with appropriate caution.» La guida alla sicurezza della specifica chiede inoltre ai client di avvisare l’utente che i server MCP girano con gli stessi privilegi del client. Una riga aggiunta a .mcp.json è quindi il nome di un programma che girerà sulla macchina di ognuno nel team, con i suoi permessi.
Che cos’è il tool poisoning?
Il modello decide quando e come chiamare un tool guardandone il nome e la descrizione. Invariant Labs, in un articolo del 1º aprile 2025, ha descritto la falla che si apre qui: il modello legge la descrizione per intero, mentre l’utente nell’interfaccia ne vede di solito una versione semplificata. Il tool poisoning consiste nel nascondere in quella descrizione istruzioni che il modello legge e l’utente non vede. L’esempio di Invariant è un tool che somma due numeri:

Il codice del server non fa nulla di dannoso: somma due numeri. Il danno lo fa il modello. Segue l’istruzione nella descrizione, legge due file e ne manda il contenuto al server nell’argomento sidenote. L’istruzione gli chiede anche di non dirlo all’utente. Invariant ha provato questo tool con Cursor e ha mostrato l’agente che faceva trapelare il file mcp.json dell’utente. La specifica MCP chiede ai client di mostrare all’utente gli input di un tool prima di chiamare il server, perché non escano dati.
Invariant richiama l’attenzione su altre due cose. La prima è il rug pull: un server malevolo può cambiare la descrizione di un tool dopo che il client lo ha approvato. Anche secondo la specifica, la lista dei tool di un server può cambiare nel tempo. La seconda è la contromisura che raccomandano: fissare la versione del server e dei suoi tool.
La specifica MCP non usa il nome «tool poisoning», ma guarda il problema allo stesso modo: le descrizioni che spiegano il comportamento di un tool vanno considerate non attendibili, a meno che non vengano da un server attendibile. Il blog sulla sicurezza di Microsoft dice la stessa cosa: una modifica alla descrizione di un tool può dirottare il comportamento dell’agente con la stessa efficacia di una modifica al suo system prompt.
C’è anche uno studio che misura quanto spesso questo attacco riesce. MCPTox ha costruito 1.348 casi di test avvelenati su 353 tool di 45 server MCP reali e li ha provati su 20 configurazioni di modelli. Il successo medio degli attacchi è stato del 36,5%; il tasso più alto, il 72,8%, con o1-mini. Il modello che rifiutava più spesso l’attacco era Claude-3.7-Sonnet, e anche lì il tasso di rifiuto restava sotto il 3%. Sono modelli del 2025, l’anno in cui è stata scritta la prima versione dell’articolo; i modelli di oggi non sono stati misurati in questo studio.
Nella MCP Top 10 di OWASP, ancora in beta, il terzo punto (MCP03) è Tool Poisoning. La pagina di dettaglio del punto dice che una descrizione del genere si può riconoscere leggendola prima dell’installazione, ed elenca cinque segnali. La domanda «Il codice del server» nella checklist qui sotto viene da questi segnali.
Perché un agente fa la cosa sbagliata mentre legge una issue?
La seconda strada passa dal contenuto che il server porta. La descrizione del tool può essere pulita; ma se il tool recupera una issue, una pagina web o un messaggio di chat, anche quel testo entra nel contesto del modello, e anche l’istruzione che contiene viene letta. Si chiama prompt injection indiretta.
Un esempio di Invariant Labs del 26 maggio 2025 lo ha mostrato con il server MCP ufficiale di GitHub. Un attaccante apre una issue in un repository pubblico. Quando l’utente chiede al suo agente di guardare le issue aperte, l’agente legge quella issue, porta nel proprio contesto informazioni dai repository privati dell’utente e le scrive in una pull request che apre lui stesso nel repository pubblico. Gli autori scrivono che non è un bug nel codice del server MCP di GitHub: il problema sta nell’architettura del sistema di agenti.
Il pericolo non sta in una singola capacità, ma nel fatto che stiano insieme: lo stesso agente può leggere testo dall’esterno, accedere a dati privati e scrivere dove tutti possono vedere. Invariant consiglia di limitare l’agente a un solo repository per sessione. Approvare ogni chiamata a un tool, da solo, non basta: secondo gli autori molti utenti attivano «Always Allow» e smettono di seguire le azioni una per una. La documentazione di Claude Code fa lo stesso avvertimento: «Servers that fetch external content can expose you to prompt injection risk.»
La stessa strada può portare l’agente a scrivere la propria configurazione MCP. Secondo il record CVE-2025-54135 della NVD, in Cursor prima della versione 1.3.9, se .cursor/mcp.json non esisteva ancora, una prompt injection indiretta poteva spingere l’agente a scrivere quel file, e il codice poteva girare senza l’approvazione dell’utente. Oggi Claude Code conta .mcp.json tra i file protetti e non approva mai da solo una scrittura su quel file, tranne che nella modalità che salta tutte le richieste di permesso. Neanche Cursor lascia che l’agente modifichi i file di configurazione senza approvazione. Se una pull request aperta da un agente tocca il file MCP, guarda chi ha chiesto quella modifica.
Anche il codice del server deve reggere a quel testo. Secondo la specifica MCP i tool li chiama il modello; quindi anche gli argomenti li scrive il modello. Se un testo che il modello legge può guidarlo, quel testo può decidere anche l’argomento. I record pubblicati dalla NVD per il server Git MCP di riferimento (mcp-server-git) mostrano due bug da cercare in un codice del genere:
| Record | Che cosa succedeva | Corretto in |
|---|---|---|
| CVE-2025-68144 | git_diff e git_checkout passavano a git come opzione un argomento che iniziava con -; con --output= si poteva sovrascrivere un file | 2025.12.17 |
| CVE-2025-68145 | Anche quando il server era limitato a un repository con --repository, non controllava che il percorso in una chiamata a un tool restasse dentro quel repository | 2025.12.17 |
| CVE-2026-27735 | git_add accettava percorsi con ../ che uscivano dal repository | 2026.1.14 |
Fonte: record della NVD, 18 ottobre 2026. La NVD ha pubblicato i primi due il 17 dicembre 2025.
Le correzioni dicono anche che cosa guardare: rifiutare un argomento che inizia con -, risolvere il percorso richiesto seguendo i link simbolici e controllare che resti dentro la cartella consentita.
Quando gli strumenti avviano un server MCP del repository?
Ogni strumento fa passare da una porta diversa un server che arriva con il repository. La tabella qui sotto riporta quello che abbiamo letto il 18 ottobre 2026 nella documentazione di ogni strumento:
| Strumento | Prima dell’avvio | In esecuzione non interattiva | Quando la configurazione cambia |
|---|---|---|---|
| Claude Code | Chiede l’approvazione per ogni server separatamente. In una cartella non attendibile ignora le approvazioni committate nel repository. | Li carica senza chiedere in claude -p, nell’Agent SDK e nelle sessioni cloud. | La documentazione non lo dice. L’approvazione è salvata con il nome del server. |
| Cursor | Ogni connessione MCP e ogni chiamata a un tool richiedono approvazione. La fiducia nell’area di lavoro è disattivata per impostazione predefinita. | Nella CLI, --approve-mcps approva tutti i server. | La documentazione non lo dice. |
| Codex | Legge il file del progetto solo in un progetto attendibile. | La documentazione non lo dice. | La documentazione non lo dice. |
| Gemini CLI | La fiducia nelle cartelle è disattivata per impostazione predefinita. Se è attiva, in una cartella non attendibile non si collega a nessun server MCP. | La documentazione non lo dice. | La documentazione non lo dice. |
| GitHub Copilot | CLI: li carica dopo che hai dato fiducia alla cartella. VS Code: dipende da Workspace Trust. | La modalità -p della CLI: li carica se la cartella è attendibile, altrimenti li salta. | VS Code: non chiede di nuovo in un’area di lavoro attendibile. |
Fonte: la documentazione di ogni strumento, 18 ottobre 2026. «La documentazione non lo dice»: nelle pagine che abbiamo letto quel giorno non abbiamo trovato una frase che descriva questo caso. La documentazione non dice nemmeno che cosa succede ai server del repository in Gemini CLI quando la fiducia nelle cartelle è disattivata. Check Point scrive che Cursor chiede di nuovo a ogni modifica dalla versione 1.3; nella documentazione di Cursor questa frase non c’è.
La parola che ricorre di più nella tabella è fiducia. La maggior parte degli strumenti non apre i server del repository uno per uno, ma insieme alla fiducia data a una cartella o a un’area di lavoro. Per questo la documentazione di VS Code ti dice di guardare la configurazione MCP prima di considerare attendibile un repository, perché i server MCP locali possono eseguire codice sulla tua macchina.
Conta anche con quanti clic si supera la domanda sulla fiducia. Adversa AI, nel suo articolo TrustFall del 7 maggio 2026, scrive che le quattro CLI testate (Claude Code, Gemini CLI, Cursor CLI e Copilot CLI) potevano eseguire i server MCP definiti nel repository non appena veniva accettata la fiducia nella cartella, e che in tutte e quattro l’opzione predefinita era «Yes/Trust». Secondo l’articolo, in Claude Code 2.1.129 a renderlo possibile erano le impostazioni enableAllProjectMcpServers e enabledMcpjsonServers committate nel repository. La documentazione attuale di Claude Code dice che in una cartella non attendibile queste impostazioni del repository vengono ignorate; che cosa succede dopo che hai dato fiducia alla cartella, la documentazione non lo dice.
Il 18 giugno 2026 Google ha smesso di servire Gemini CLI agli utenti gratuiti e agli abbonati Google AI Pro e Ultra, indirizzandoli ad Antigravity CLI; con una chiave API a pagamento o una licenza aziendale puoi continuare a usare Gemini CLI. Il 28 ottobre 2026 abbiamo letto la documentazione di Antigravity CLI. Secondo la sua pagina su MCP, i server del repository stanno in .agents/mcp_config.json e quelli dell’utente in ~/.gemini/config/mcp_config.json; in una pull request il file da tenere d’occhio è il primo. Per impostazione predefinita, un tool MCP che le tue regole di autorizzazione non citano chiede l’approvazione prima di essere chiamato. La CLI ti chiede anche se consideri attendibile la cartella. La documentazione non dice se i server del repository aspettano questa risposta né se la CLI chiede di nuovo quando la configurazione cambia.
Che cosa succede se il server cambia dopo l’approvazione?
L’approvazione si dà una volta, mentre il server continua a cambiare. La vulnerabilità che Check Point Research ha chiamato MCPoison ha mostrato dove può portare: Cursor legava la fiducia al nome del server e non controllava se il comando o gli argomenti fossero cambiati. Secondo il record della NVD (CVE-2025-54136), in Cursor 1.2.4 e versioni precedenti, chiunque potesse scrivere in un repository condiviso poteva sostituire un server innocuo, approvato una volta da un collega, con un comando malevolo, senza alcun avviso né nuova richiesta di approvazione.
Check Point ha segnalato la vulnerabilità a Cursor il 16 luglio 2025, e Cursor l’ha corretta il 29 luglio 2025 con la versione 1.3. Secondo Check Point, ora ogni modifica alla configurazione, anche aggiungere uno spazio, richiede una nuova approvazione. Nella documentazione di Cursor non abbiamo trovato una frase che descriva questo comportamento.
La documentazione degli altri strumenti o dà a questa domanda una risposta diversa, o non la tocca. VS Code è esplicito: in un’area di lavoro attendibile, i server di .vscode/mcp.json e del .mcp.json nella root possono avviarsi senza una richiesta di approvazione MCP separata, «including after their configuration changes». In Claude Code la lista delle approvazioni (enabledMcpjsonServers) contiene i nomi dei server; se chiede di nuovo quando il comando cambia sotto lo stesso nome, la documentazione non lo dice. Nemmeno la documentazione MCP di Cursor, Codex e Gemini CLI ha una frase su questo.
Per confronto: Codex e Gemini CLI rispondono alla stessa domanda per gli hook. Codex ti chiede di esaminare e approvare la definizione esatta di un hook che arriva dal repository prima di eseguirlo. Gemini CLI tratta un hook a cui sono cambiati il nome o il comando come un hook nuovo e non attendibile, e avvisa prima di eseguirlo. Per i server MCP, nessuna delle due documentazioni ha una frase simile.
Anche i tool di un server possono cambiare mentre gira. Il server lo segnala con una notifica (list_changed); in una sessione interattiva, Claude Code scarica di nuovo la lista dei tool quando arriva la notifica. Se le descrizioni cambiate vengano mostrate all’utente, la documentazione non lo dice.
In breve, l’approvazione sul tuo portatile ha visto la prima versione del server. Anche se il nome resta lo stesso, il posto in cui puoi vedere le versioni successive è il diff della pull request.
Un agente che gira in CI carica i server MCP del repository?
In un’esecuzione non interattiva non c’è nessuno che approvi. La documentazione di Claude Code lo scrive chiaramente: nelle esecuzioni claude -p, nelle sessioni dell’Agent SDK e nelle sessioni cloud, Claude Code non può mostrare la richiesta di approvazione e carica i server del progetto senza chiedere. La tabella nella documentazione sui permessi prende un’esecuzione claude -p in una cartella mai considerata attendibile e descrive i suoi server .mcp.json in una frase: «Connected without asking, approved or not.»
Prima di lanciare claude -p in un repository che non hai scritto tu, la documentazione di Claude Code indica queste strade:
--setting-sources user: non legge né i file di impostazioni del progetto né il suo.mcp.json.--bare: non legge dal progetto hook, skill, subagent, plugin né server di.mcp.json; il bloccoenvdel progetto si applica comunque.--strict-mcp-config: usa solo i server che passi con--mcp-config.disabledMcpjsonServers: blocca un server per nome, in ogni modalità di autorizzazione.
Gli altri strumenti si comportano in modo diverso. La modalità prompt di Copilot CLI (copilot -p) carica da sola i server del progetto se la cartella è già attendibile, altrimenti li salta. In Cursor CLI il flag --approve-mcps approva automaticamente tutti i server MCP, e --trust considera attendibile l’area di lavoro senza chiedere in modalità headless. Se un file di workflow aggiunge uno di questi flag, leggilo anche come una modifica MCP. La documentazione di Codex e quella di Gemini CLI non dicono che cosa succede a un server del repository in un’esecuzione non interattiva.
Sul lato della GitHub Action che gira sulle pull request c’è un’altra distinzione. La documentazione sulla sicurezza di claude-code-action spiega che, quando l’action gira su una pull request, ripristina dal branch di base una lista fissa di percorsi di configurazione di Claude (8 percorsi, tra cui .mcp.json) prima che Claude parta; le versioni portate dalla pull request restano in una cartella a parte, solo come riferimento. Il resto del working tree resta com’è nella pull request. La claude-code-base-action, di livello più basso, invece non fa questo ripristino. L’articolo TrustFall di Adversa aveva scritto che con l’uso predefinito dell’action ufficiale la domanda sulla fiducia non compare mai e che l’attacco funziona contro i branch delle pull request senza che nessuno tocchi niente; la documentazione attuale dell’action descrive il ripristino di cui sopra.
Nell’agente cloud di GitHub Copilot, invece, la configurazione MCP non è un file del repository: si inserisce nelle impostazioni del repository su GitHub.com, e Copilot code review usa la stessa configurazione. Per questo non compare nel diff della pull request. Secondo la documentazione, l’agente usa questi tool senza chiedere approvazione; per questo GitHub consiglia di mettere in allowlist, uno per uno, tool in sola lettura.
Che cosa c’è nella lista dei rischi MCP di OWASP?
La MCP Top 10 di OWASP raccoglie i rischi specifici di MCP in 10 voci. La pagina stessa dice che la lista è in beta. Il 18 ottobre 2026, su owasp.org le voci erano queste:
| Voce | Titolo | Di che cosa parla |
|---|---|---|
| MCP01 | Token Mismanagement & Secret Exposure | Credenziali scritte nel codice, token di lunga durata, segreti che restano nella memoria del modello o nei log del protocollo. |
| MCP02 | Privilege Escalation via Scope Creep | Permessi definiti in modo vago si allargano nel tempo e danno all’agente più poteri del necessario. |
| MCP03 | Tool Poisoning | I tool, i plugin o i loro output su cui il modello si basa vengono alterati per guidarlo. |
| MCP04 | Software Supply Chain Attacks & Dependency Tampering | Una dipendenza compromessa cambia il comportamento dell’agente o apre una backdoor. |
| MCP05 | Command Injection & Execution | L’agente costruisce ed esegue comandi, script, chiamate API o codice a partire da input non attendibili. |
| MCP06 | Prompt Injection via Contextual Payloads | La injection classica in versione modello: l’interprete è il modello, il payload è testo. |
| MCP07 | Insufficient Authentication & Authorization | Server, tool o agente non verificano bene le identità né controllano gli accessi. |
| MCP08 | Lack of Audit and Telemetry | Senza un registro delle chiamate ai tool, dopo non si riesce a capire che cosa è successo. |
| MCP09 | Shadow MCP Servers | Server messi in piedi per prova o per comodità, fuori dal controllo di sicurezza dell’organizzazione. |
| MCP10 | Context Injection & Over-Sharing | Un contesto condiviso o dai confini poco chiari espone le informazioni di un task o di un utente a un altro. |
Fonte: owasp.org, 18 ottobre 2026. Il repository GitHub del progetto chiama MCP06 «Intent Flow Subversion» e indica come data della prossima versione ottobre 2026; i nomi possono cambiare.
Usa la lista come un vocabolario comune, non come uno standard: serve a dare un nome a un rilievo. La maggior parte delle domande qui sotto corrisponde a MCP01, MCP03, MCP04, MCP05 e MCP06.
Che cosa controllare in una pull request che modifica un file MCP?
Tutto quello che abbiamo visto porta a una sola conclusione: la schermata di approvazione ha visto la prima versione del server, e ogni modifica successiva la puoi leggere nella pull request. L’esempio qui sotto mette insieme tre cose che una pull request può cambiare in un file MCP:
![ESEMPIO. Un server con lo stesso nome può eseguire un altro programma. .cursor/mcp.json · diff: { / "mcpServers": { / "docs": { / - "command": "npx", / - "args": ["-y", "docs-mcp@1.4.2"] / + "command": "node", / + "args": ["scripts/docs-server.js"] / }, / + "tracker": { / + "command": "npx", / + "args": ["-y", "tracker-mcp@latest"], / + "env": {"GH_TOKEN": "${env:GH_TOKEN}"} / + } / } / }. docs: Stesso nome, comando nuovo: ora gira uno script del repository. @latest: Versione non fissata: ogni avvio può portare altro codice. GH_TOKEN: Quale token va al server, e con quali permessi?](/blog/img/mcp-security-diff-it.webp?v=931d5760f5f5baba)
${env:GH_TOKEN} è la sintassi delle variabili d’ambiente di Cursor.La prima modifica è la più facile da non notare: il nome docs è rimasto lo stesso, ma ora gira un altro programma, e questo programma è uno script del repository. Quello script può cambiare in questa pull request o nelle successive; quello che fa il server ora dipende dalla review di quel file. Il secondo server scaricherà a ogni avvio la versione del pacchetto in vigore quel giorno, e prenderà un token dall’ambiente.
In un diff del genere, passa in rassegna queste domande nell’ordine:

- Il comando, gli argomenti e l’indirizzo. La guida alla sicurezza di MCP chiede ai client che installano un server con un clic di mostrare il comando che verrà eseguito, con i suoi argomenti e senza troncarlo. In una pull request queste righe le hai già davanti; se il comando esegue uno script del repository, leggi anche quello script. Per un server remoto, guarda a chi appartiene l’indirizzo e se usa
https. La guida spiega anche, a parte, che un indirizzo OAuth fornito da un server malevolo può arrivare fino all’esecuzione di codice sul client. - La versione.
@latest, o il nome di un pacchetto senza versione, può portare codice diverso a ogni avvio. Invariant consiglia di fissare la versione del server e dei suoi tool; nella lista di OWASP la supply chain è una voce a sé (MCP04). - Un server che cambia con lo stesso nome. MCPoison è nato proprio da questa riga. Se l’approvazione è legata a un nome, finché il nome resta lo stesso un comando nuovo può stare dietro alla vecchia approvazione. Leggi una modifica del genere come un server nuovo.
- Approvazioni che arrivano con la pull request. Claude Code scrive le impostazioni
enableAllProjectMcpServerseenabledMcpjsonServersin.claude/settings.local.jsonquando dai la tua approvazione; registrano una scelta personale. Vederle nel file condiviso.claude/settings.jsonvuol dire distribuire a tutti l’approvazione di una sola persona. In Gemini CLI,"trust": truesalta tutte le conferme per quel server, e la documentazione lo consiglia solo per server che controlli completamente; se valga anche quando è scritto nel file del progetto, la documentazione non lo dice. - Segreti. Guarda quale variabile entra nei campi
enveheaders, e a che cosa può accedere quel token. Claude Code e Cursor permettono di leggere una chiave da una variabile d’ambiente invece di scriverla nel file; così il segreto esce dal file, ma questo non gli impedisce di arrivare al server. Gemini CLI non manda al server le variabili sensibili dell’ambiente di base, ma considera una variabile scritta esplicitamente nel campoenvcome consenso informato dell’utente e non la oscura. Chi legge quella riga nella pull request è chi dà quel consenso. - Comandi di supporto. Claude Code esegue
headersHelpercome un «arbitrary shell command»; in Codex anchehttp_headers_helperè un comando locale. Leggili come leggeresti il server stesso. - Tool che leggono testo esterno. Se un server che legge issue, pagine web o chat viene aggiunto accanto a un server che accede a dati privati, guardali insieme. L’esempio di GitHub è nato proprio da questa coppia.
- Il codice del server. Se il codice è nella pull request, cerca argomenti che iniziano con
-e percorsi che escono dal repository (i record di Git MCP visti sopra). Nelle descrizioni dei tool cerca i segnali elencati da OWASP MCP03: frasi all’imperativo rivolte al modello, percorsi di file sensibili come~/.ssho.env, frasi che dicono di «inviare» a un indirizzo, caratteri a larghezza zero e istruzioni nascoste in commenti HTML. - CI. Il workflow esegue l’agente sul branch della pull request, con le impostazioni del progetto caricate? Controlla se in Claude Code ci sono
--setting-sources usero--strict-mcp-config, e in Cursor CLI il flag--approve-mcps.
Scrivere queste domande in un file di regole, da solo, non basta: una modifica si legge solo in review. La stessa review vale per gli hook in .claude/settings.json, che abbiamo visto a parte nell’articolo sugli hook. Come ricorda la documentazione sulla sicurezza di Claude Code, leggere .mcp.json non mostra tutti i server che una sessione può caricare: ci sono anche server che arrivano dalle impostazioni utente e dai plugin.
Neanche un bot di code review è fuori da questo problema: anche lui è un modello che legge un testo scritto dall’autore della pull request. In diffox, nel passaggio che decide se un rilievo va scartato perché «l’autore l’ha fatto apposta», la descrizione della pull request viene messa tra tag e al modello viene detto che sono dati, non un’istruzione; un tag scritto dentro la descrizione stessa viene neutralizzato. Il Security Agent, che gira in ogni review, cerca injection, autenticazione e autorizzazione rotte, segreti esposti, SSRF e deserializzazione o gestione dei percorsi non sicure (abbiamo descritto come funziona diffox in un articolo a parte).
Domande frequenti
Che cos’è il tool poisoning in MCP?
Il tool poisoning consiste nel nascondere nella descrizione di un tool MCP istruzioni che il modello legge e l’utente non vede. Nell’esempio di Invariant Labs, la descrizione di un tool che somma due numeri chiede al modello di leggere la chiave SSH dell’utente, mandarla al server in un argomento e non dirlo all’utente. È la terza voce (MCP03) della OWASP MCP Top 10. Si può riconoscere leggendo la descrizione: frasi all’imperativo rivolte al modello, percorsi di file sensibili e caratteri invisibili sono i segnali più noti.
Che cos’è la OWASP MCP Top 10 e qual è l’ultima versione?
È la lista in cui OWASP raccoglie 10 rischi specifici di MCP. Al 18 ottobre 2026, la lista su owasp.org è in beta e le sue voci sono numerate nella forma «MCP01:2025»; va da Token Mismanagement & Secret Exposure a Context Injection & Over-Sharing. Il repository GitHub del progetto indica come data della prossima versione ottobre 2026, e lì una voce ha un nome diverso da quello del sito. Quando citi una voce, scrivi anche la sua data.
Il file .mcp.json va committato nel repository?
La documentazione di Claude Code lo consiglia, così tutto il team usa gli stessi tool. Una volta committato, il file fa parte del codice e va esaminato come codice: comando, versione, variabili d’ambiente e impostazioni di approvazione. Le approvazioni personali (come enabledMcpjsonServers) vanno invece in .claude/settings.local.json, dove le scrive Claude Code stesso.
Claude Code esegue i server MCP del repository senza chiedere?
In una sessione interattiva no: chiede l’approvazione per ogni server di .mcp.json separatamente e, in una cartella non attendibile, ignora le impostazioni di approvazione committate nel repository. Nelle esecuzioni claude -p, nelle sessioni dell’Agent SDK e nelle sessioni cloud, invece, non può mostrare la richiesta di approvazione e quindi carica i server del progetto senza chiedere. Per evitarlo puoi usare --setting-sources user, --bare, --strict-mcp-config o disabledMcpjsonServers.
Come si disattivano i server MCP del repository quando un agente di programmazione gira in CI?
In Claude Code, --setting-sources user non legge né le impostazioni del progetto né .mcp.json; --strict-mcp-config usa solo i server che passi tu. Sulle pull request, claude-code-action ripristina .mcp.json dal branch di base. La modalità -p di Copilot CLI salta i server del progetto in una cartella non attendibile. In Cursor CLI, --approve-mcps approva tutti i server; non usare questo flag in un job che gira sul branch della pull request. La documentazione di Codex e quella di Gemini CLI non descrivono questo caso.
Uno strumento di code review con IA individua una modifica MCP?
Dipende dallo strumento. diffox legge il diff della pull request, e il Security Agent gira in ogni review: cerca injection, autenticazione e autorizzazione rotte, segreti esposti, SSRF e deserializzazione o gestione dei percorsi non sicure. diffox non ha una regola a parte per MCP; le domande di questo articolo le fa chi esegue la review. Quando scegli uno strumento di code review, chiedi anche come legge la descrizione della pull request: in diffox, il passaggio che controlla se un rilievo era voluto legge la descrizione come dati, non come un’istruzione.