AI and Automation

URL MCP a vita breve: il pattern TTL per gli agenti AI nel 2026

Trend Micro ha contato 1.467 server MCP esposti su internet senza autenticazione. URL con TTL di minuti, non giorni, chiudono il buco.

4 giugno 20266 min di lettura
clear glass hour glass on black surface

Un URL di un server MCP è una credenziale. Sembra un normale endpoint HTTPS, ma chi lo possiede può chiamare gli strumenti dietro. Se un agente ha l'URL, l'agente può leggere il database, scrivere nel canale, far partire il deploy. Se l'URL finisce nelle mani di chiunque altro, può fare le stesse cose.

Per questo gli URL MCP a lunga durata sono il default sbagliato. La soluzione: URL a vita breve con TTL di minuti, token con scope stretto, rotazione a ogni uso. Il pattern non è nuovo. AWS lo chiama presigned URL e lo spedisce dal 2011 per S3. Quello che cambia nel 2026 è che adesso gli agenti AI stanno dall'altra parte di questi URL, e il tasso di esposizione è abbastanza grande da essere misurato.

Il problema in numeri

Trend Micro ha scansionato la rete pubblica alla ricerca di endpoint MCP a fine 2025 e ne ha trovati 492 senza autenticazione del client e senza cifratura del traffico. L'aggiornamento di aprile 2026 porta il conto a 1.467 server, quasi un triplicarsi in sei mesi. Il 74% gira su AWS, Azure, GCP e Oracle. Il 90% offre accesso diretto in lettura a una sorgente dati. Un prompt in linguaggio naturale basta per esfiltrare.

L'altro modo in cui le cose cedono è il bypass dell'autenticazione. La CVE-2026-33032 (MCPwn) è una CVSS 9.8 contro l'integrazione MCP di Nginx UI che prende il controllo del server in due richieste HTTP. Lo sfruttamento attivo è stato confermato a maggio 2026. Il pattern è lo stesso visto in ogni generazione precedente di endpoint remoti: l'URL esiste, le credenziali sono statiche, la rotazione non avviene mai.

Perché gli URL a lunga durata cedono

Un URL di un server MCP finisce in quattro posti dove non dovrebbe stare: log di chat, file di configurazione dell'IDE, screenshot nei ticket di supporto, cronologia git. Nessuno di questi è un incidente. Sono i sottoprodotti naturali del modo in cui sviluppatori e agenti lavorano. Un URL incollato in una conversazione con Claude vive in quel thread finché il thread non viene cancellato. Un URL committato in un repo privato vive lì finché il repo non viene esposto o l'account GitHub di un collaboratore viene compromesso.

Se l'URL vale un anno, ognuna di quelle copie è una backdoor funzionante per un anno. Se l'URL vale 15 minuti, la backdoor si chiude prima che la fuga raggiunga un attaccante in grado di sfruttarla.

La forma del pattern TTL

La forma che usiamo, presa dal pattern presigned URL che AWS documenta per l'accesso agli oggetti, ha quattro parti:

  1. TTL di accesso breve. L'URL o il token di accesso valgono da 5 a 60 minuti. La maggior parte delle chiamate degli agenti in produzione termina in pochi secondi, quindi il limite superiore conta solo per i job di lunga durata.
  2. Refresh lungo, ruotato a ogni uso. Un refresh token valido 30-90 giorni, ruotato ogni volta che viene scambiato. Se lo stesso refresh token viene presentato due volte, entrambi vengono revocati.
  3. Scope stretto per token. Se l'agente serve solo a leggere uno storage account, il token dice quello. Nessun bearer token nel 2026 dovrebbe poter fare qualunque cosa su qualunque risorsa.
  4. Audit a ogni cambio di stato. Token acquisito, rinnovato, avviso di scadenza, scaduto, revocato. Il punto non è la riga di log; è che un refresh token trapelato salti fuori come evento di rotazione duplicata in ore, non in mesi.

La spina dorsale dello standard è OAuth 2.1 con PKCE, che la revisione di giugno 2025 della specifica di autorizzazione MCP ha adottato. La stessa revisione ha spinto i server MCP nel solo ruolo di resource server OAuth: validano token emessi da un authorization server esterno, non li emettono. Questa separazione è quello che rende il pattern TTL applicabile. Il resource server non può continuare ad accettare un token oltre la sua scadenza, neanche volendo.

Quanto è breve

Il numero giusto dipende dal profilo della chiamata. Per agenti che reagiscono in tempo reale al prompt di un utente, 5-15 minuti bastano. Per job batch che si aprono a ventaglio su centinaia di strumenti, 60 minuti danno respiro all'orchestratore senza allungare di molto la finestra di leak. Non abbiamo ancora trovato un caso in produzione dove un access token da 24 ore sia la risposta giusta. Se il job ha bisogno di tanto tempo, ha bisogno di un loop di refresh.

Per confronto, AWS permette di codificare il TTL direttamente nell'URL per S3 (massimo 12 ore via console, 7 giorni via CLI) e offre la condition s3:signatureAge nelle bucket policy che rigetta richieste in cui la firma è più vecchia di N minuti, indipendentemente da cosa dice l'URL (AWS presigned URL best practices, PDF). È il secondo controllo quello da copiare. Il TTL lo applica il server, non il client.

Il buco sui refresh token

Il pattern dipende dal fatto che il client MCP implementi la rotazione del refresh token. Questa implementazione manca nella maggior parte dei client sul mercato ad aprile 2026. SecureCoders traccia la matrice di supporto e riporta che nessun client MCP CLI maggiore spedisce oggi la rotazione del refresh token. La conseguenza pratica: un access token scade, il client non può ruotarlo silenziosamente, e all'utente umano viene chiesto di autenticarsi di nuovo. Il pattern funziona comunque, ma il costo UX cade su chi opera l'agente, non sulla piattaforma.

Finché i client non chiudono il buco, due rimedi aiutano. Tenere davanti al server un gateway MCP che possiede il loop di refresh e presenta token freschi ai client upstream. Oppure accettare il re-auth interattivo come feature: forzare un umano nel loop ogni ora non è il modo peggiore in cui può fallire un agente con accesso in scrittura al database.

Cosa loggare

Cinque eventi coprono il ciclo di vita e dovrebbero finire nello stesso stream di audit dei log applicativi:

  • token.acquired con subject, scope e TTL.
  • token.refreshed con id del vecchio token, id del nuovo, IP di origine.
  • token.expiry_warning all'80% del TTL, così il client può ruotarlo in anticipo.
  • token.expired quando il resource server rifiuta.
  • token.revocation_detected quando un refresh token già ruotato viene rigiocato.

L'ultimo è l'allarme. Un refresh token rigiocato significa due cose: o il client ha riprovato dopo un fallimento parziale, e va tutto bene in silenzio; oppure due soggetti tengono lo stesso refresh token, e questo non va bene e deve mandare un page.

Dove il pattern non si applica

Tre casi resistono. Primo, server MCP locali che non lasciano mai la macchina dello sviluppatore: un TTL aggiunge frizione senza comprare sicurezza. Secondo, agenti che girano su reti isolate senza egress: il vettore di leak è chiuso, la rotazione è overhead. Terzo, lo stesso server MCP consumato da decine di migliaia di utenti low-trust: il collo di bottiglia è l'autenticazione, e la risposta è un gateway con scope per utente, non TTL più corti a livello di URL.

Per tutto il resto (server MCP cloud, accesso di collaboratori esterni, agenti che chiamano strumenti attraverso confini organizzativi, qualunque cosa Trend Micro possa trovare con un port scan) il default dovrebbe essere TTL di minuti e un loop di refresh che nessuno deve pensare finché qualcosa non va storto.

Foto di Milad Fakurian su Unsplash

Domande frequenti

Come si differenzia un URL MCP a vita breve da una normale scadenza JWT?
La claim exp di un JWT è metà della storia. L'altra metà è la rotazione del refresh token che ti dà un nuovo JWT. La maggior parte dei deployment MCP oggi mette una exp di settimane o mesi e non ruota mai il refresh token, quindi la sicurezza pratica è la stessa di una chiave statica. Il pattern TTL sistema entrambe le metà: minuti sull'access token, rotazione a ogni refresh.
Cosa succede ai job di agenti di lunga durata quando l'access token scade a metà chiamata?
Il comportamento corretto è un refresh silenzioso fatto dal client MCP prima della scadenza, tipicamente all'80% del TTL. Se il client non supporta il refresh, il job fallisce a metà e va riavviato. Per agenti batch che girano per ore, un TTL di 60 minuti con refresh proattivo è il compromesso comune. Più di così è raro nella pratica.
Serve un authorization server OAuth separato per usare il pattern TTL?
La revisione di giugno 2025 della specifica MCP presume di sì. Il server MCP è solo resource server: valida i token, non li emette. In pratica si può usare qualunque provider OAuth 2.1 (WorkOS, Auth0, Keycloak o uno proprio) come authorization server. Avere entrambi i ruoli nello stesso processo è ammesso dalla specifica ma annulla la separazione che rende il pattern TTL applicabile.

Studio

Inizia un progetto.

Un partner unico per il prodotto digitale che devi costruire. Produzione più veloce, tecnologie moderne, costi ridotti. Un team, una fattura.