Salta al contenuto principale

Prompt injection: separare gli intenti dalle tecniche

AI Security - Questo articolo fa parte di una serie.
Parte 1: Questo articolo

Per le prime due settimane in cui ho studiato le prompt injection ho fatto la cosa sbagliata: collezionavo prompt. Leggevo un thread, trovavo una formulazione che aveva funzionato contro qualche modello, la incollavo negli appunti. Alla fine avevo un file di sessanta righe che non spiegava niente. Sessanta casi singoli.

Gran parte del materiale online è organizzato così: un copia incolla di prompt funzionanti che smettono di essere utili alla successiva release. Inoltre, questi prompt, per quanto facilmente analizzabili, non aiutano realmente nel creare una difesa adeguata e reale.

Quindi ho buttato via la mia collezione di prompt e ho iniziato a ragionare su cosa rendeva questi prompt validi e quali sono i punti centrali su cui si costruiscono questi attacchi.

Cinque cose che chiamavo tutte “tecnica”
#

La distinzione che mi ha sbloccato è che in un tentativo di injection ci sono cose di natura diversa, e io le tenevo tutte nella stessa lista:

  1. l’intento, cioè cosa voglio ottenere
  2. la tecnica, cioè come ristrutturo la conversazione per ottenerlo
  3. l’evasione, cioè come faccio passare il testo attraverso i filtri
  4. gli amplificatori, che non cambiano la tecnica ma la rendono affidabile
  5. le utility: automazione, generazione di varianti, misura dei risultati

Scritto così sembra ovvio. Non lo era nei miei appunti, dove leetspeak e narrative injection stavano appaiate come se fossero nella stessa categoria. La prima traveste il testo, la seconda ristruttura il contesto: sono due operazioni di natura diversa, e finché le tenevo insieme non riuscivo a ragionarci sopra. Nella pratica quasi sempre si combinano, ma questo non le rende la stessa cosa, e chiamarle con lo stesso nome toglie soltanto chiarezza.

Cosa voglio ottenere
#

L’intento è la parte che conta per un threat model. Prendiamo come esempio il leak del prompt di sistema, cioè farsi restituire dal modello le istruzioni con cui è stato configurato.

Il rischio non è il testo in sé. Quelle istruzioni descrivono cosa l’applicazione permette e cosa vieta, quali strumenti può chiamare, quali dati considera propri: leggerle significa avere davanti la logica di autorizzazione scritta in chiaro, e sapere esattamente dove spingere al tentativo successivo. Un leak raramente è il danno, è la ricognizione.

Ci si può arrivare in due modi. A turno unico, con un singolo messaggio costruito per ottenere subito la restituzione delle istruzioni. Oppure in più turni, costruendo il contesto poco a poco: si comincia con richieste innocenti, si stabilisce una convenzione, e solo dopo si chiede il pezzo che serve.

La seconda mi interessa più della prima perché sposta il bersaglio. Non c’è un messaggio malevolo da intercettare: preso uno per uno, nessuno di quei turni ha niente di sospetto. È la traiettoria a essere l’attacco, e una difesa che guarda un messaggio alla volta non ha modo di vederla.

Come convincere un modello
#

Ecco nove classi dai miei appunti su alcune tecniche utilizzate:

  • Narrative injection: incapsulare la richiesta in una finzione, un racconto, un personaggio. Sposta la richiesta dal piano “questo è un ordine” al piano “questo è il contenuto di una storia”.
  • Token smuggling: il modello non legge parole, legge token. Spezzare un termine, o farlo ricomporre a runtime, cambia quello che vede un filtro senza cambiare quello che capisce il modello.
  • End sequence: infilare nel testo i marcatori che il formato di conversazione usa per dire “qui finisce il turno dell’utente”.
  • Russian doll: annidare il payload in più livelli di codifica, e chiedere al modello di srotolarli.
  • Polarity inversion: riformulare per inversione, tipo chiedere cosa non fare in modo che l’elenco delle cose da non fare sia la risposta.
  • Priming: dettare l’inizio della risposta, perché una frase che parte con un assenso è molto più difficile da interrompere con un rifiuto.
  • Errore e riorientamento: dichiarare che qualcosa è andato storto e che le istruzioni precedenti erano sbagliate, per farsi seguire nella correzione.
  • Falsi tag di sistema: scrivere marcatori che sembrano venire dal livello superiore, e aggiungere regole come se fossero arrivate dall’alto.
  • Reiterazione: ripetere un’istruzione come se fosse un promemoria già concordato, invece di formularla come richiesta nuova.

Tre di queste, per quanto le si trovi ancora in giro come se fossero il cuore della materia, non sono la strada giusta: token smuggling, end sequence e russian doll lavorano tutte sulla forma della stringa, e un modello come Opus 5 le riconosce per quello che sono. Il grosso del materiale che si trova online insiste proprio su queste, ed è una delle ragioni per cui invecchia male. Quello che regge sta altrove: nelle tecniche che agiscono sul contesto e sull’autorità apparente di chi parla, e soprattutto nel multi turno, dove non c’è un singolo messaggio da riconoscere.

Il confine è una convenzione
#

Il modello non riceve “un’istruzione di sistema” e poi “dei dati dell’utente” come due oggetti separati. Riceve una sequenza piatta di token. La separazione esiste perché il formato della conversazione la disegna con dei marcatori, e perché l’addestramento ha insegnato al modello a trattare quei marcatori come autorevoli.

È una convenzione, non un meccanismo. Robusta, ma se riesci a scrivere qualcosa che somiglia a un confine stai giocando esattamente su quella differenza.

Da difensore il seguito è scomodo: non esiste una sanificazione dell’input che risolva il problema. Non stai filtrando codice con una grammatica, stai filtrando linguaggio naturale, dove lo stesso significato ha infinite forme.

Questa a me sembrava un’intuizione, e invece c’è chi l’ha misurata. A ottobre 2025 un gruppo di quattordici ricercatori tra OpenAI, Anthropic e Google DeepMind ha preso dodici difese pubblicate contro jailbreak e prompt injection e le ha attaccate in modo adattivo, cioè modificando la strategia contro il disegno di quella specifica difesa invece di rilanciarle contro stringhe fisse. Sono passati sopra quasi tutte con un tasso di successo superiore al 90%, e il red teaming umano ha fatto 100% su tutte quante. Difese che nei paper originali riportavano tassi di fallimento vicini allo zero. Se ti serve un argomento per non fidarti dei numeri di una difesa valutata contro esempi statici, è quello.

Le mitigazioni che restano in piedi non stanno nel testo, stanno nell’architettura. Simon Willison ha dato un nome alla combinazione da evitare, la lethal trifecta: accesso a dati privati, esposizione a contenuti non fidati, e capacità di comunicare verso l’esterno. Se un agente ha tutte e tre, un singolo contenuto avvelenato basta a farti uscire i dati di casa. Meta ci ha costruito sopra una regola operativa, la Rule of Two: finché la ricerca non sa riconoscere le injection in modo affidabile, un agente non dovrebbe avere più di due di quelle tre proprietà nella stessa sessione, e se le servono tutte e tre allora non gira da solo, ci vuole un umano che approva.

Gli amplificatori, che è la categoria che mi mancava
#

Questa categoria l’ho aggiunta per ultima, e l’ho aggiunta perché mi mancava un posto dove mettere due cose che continuavo a incontrare e che non sono né tecniche né evasioni. Non cambiano cosa chiedi. Cambiano quanto spesso funziona.

Il many-shot riempie il contesto di molti esempi del comportamento che vuoi, finché lo schema presente nella conversazione pesa più del comportamento appreso in addestramento. Non è folklore: è ricerca pubblicata, e la cosa che mi ha colpito è che l’efficacia cresce con il numero di esempi seguendo una legge di potenza, la stessa che si osserva nell’apprendimento in contesto di compiti innocui. Cioè non è una falla a sé: è il rovescio di come i modelli imparano dagli esempi che gli metti davanti. Da cui due conseguenze scomode: la leva scala con la finestra di contesto, e i modelli più capaci di imparare in contesto sono anche i più esposti.

Il prefill è mettere parole in bocca al modello precompilando l’inizio della sua risposta. Diverse API lo espongono come parametro perché è comodissimo per controllare il formato dell’output, ma è anche una leva potente: un rifiuto è molto più difficile da produrre se la risposta è già cominciata con un assenso.

Dei due, il prefill è il caso più istruttivo, perché è già stato chiuso. Dai modelli Claude 4.6 in poi una richiesta con un messaggio assistant precompilato sull’ultimo turno restituisce un errore 400, e la guida alla migrazione elenca fra gli usi storici del prefill proprio lo steer around unnecessary refusals. Cioè è il fornitore stesso a mettere per iscritto che quel parametro serviva anche a scavalcare i rifiuti.

Quello che conta non è la singola decisione, è dove è stata presa. Nessuno ha reso il modello più difficile da convincere: hanno tolto il parametro. La leva non stava nel prompt di sistema, stava nella forma dell’API, ed era una scelta di prodotto che si poteva revocare.

Da cui la regola che mi porto dietro. Se il tuo prodotto espone il prefill, o accetta contesti molto lunghi, hai già consegnato delle leve di affidabilità a chiunque, a prescindere da quale tecnica ti venga usata contro. E quando vuoi riprenderti quelle leve, il posto dove intervenire è la superficie dell’API, non il prompt.

Da qui vado avanti
#

Ho iniziato questo studio collezionando trucchi e mi sono accorto che c’era qualcosa di molto più interessante: una superficie di attacco che non è un bug da patchare ma una proprietà di come funzionano questi sistemi. Il confine tra istruzione e dato è disegnato dal formato e rispettato per addestramento, non imposto dalla macchina. Sono settimane che ci penso e continua a sembrarmi il punto più bello di tutta la faccenda.

E la cosa cambia sotto le mani mentre la studi. Le finestre di contesto crescono e con loro cresce la leva del many-shot. Escono modelli nuovi e non sai quanto del materiale che hai letto sei mesi fa valga ancora. Le API espongono parametri comodissimi che sono anche leve di attacco. Non conosco molti ambiti dove il terreno si muove così, e per chi sta imparando è una fortuna: nessuno ha finito di capirci qualcosa, quindi c’è spazio per mettersi a misurare.

Se hai delle idee da condividere o vuoi commentare quello che hai letto, scrivimi, ne parliamo volentieri.

Fonti
#

In ordine di quanto mi sono servite.

AI Security - Questo articolo fa parte di una serie.
Parte 1: Questo articolo