Injection e supply chain 💉
Injection e supply chain sono trasversali, ma non sono parole magiche. L’injection classica usa input non fidato per alterare un interprete con una grammatica separabile: query parametrizzate, escaping e allowlist sono controlli forti. La prompt injection sfrutta un modello che legge istruzioni e dati nella stessa rappresentazione linguistica: non esiste un escape perfetto. Ripeterlo non è cautela: è la differenza tra un fix e una preghiera.
Le due famiglie vanno trattate insieme solo perché entrambe attraversano tutti i domini. I meccanismi, e quindi i controlli, restano profondamente diversi.
Lo spettro dell’injection: dalla sintassi alla semantica 🌈
| Caso | Meccanismo | Difese principali |
|---|---|---|
| SQL o command injection | Input diventa sintassi eseguibile di una grammatica nota | Parametri, allowlist, privilegi minimi |
| Injection via eventi serverless | Payload dentro eventi S3/SNS/queue che una funzione esegue | Validazione del trigger, role dedicati |
| Pipeline avvelenata (PPE) | Configurazione build esegue codice sul runner | Review, runner isolati, branch protection |
| Prompt injection | Contenuto ostile devia il modello nello stesso canale delle istruzioni | Tool minimi, conferme, isolamento dati, eval avversari |
L’injection classica ha un’interessante conferma indiretta: la lista API 2023 l’ha rimossa perché ritenuta “non specifica delle API” — quando un problema è ovunque, non è di nessuno. Il punto non è che sia sparita: è che il controllo si eredita dal backend e non serve riscriverlo per le API. La prompt injection, al contrario, è nata come categoria di primo livello proprio perché il contesto la rende specifica di un runtime (il modello) che non aveva mai avuto una categoria prima.
Injection indiretta: il sotto-caso che più spesso sorprende. Il contenuto ostile non arriva dal prompt dell’utente, ma da una pagina web recuperata nel RAG, da un file caricato o dall’output di un tool. Il meccanismo fisico è più vicino alla stored XSS — pianti il payload dove un processo fidato lo consumerà più tardi — che all’injection riflessa classica. Ne consegue che difendere solo l’input di chat è inutile: deve farlo ogni superficie che diventa contesto.
Il fork della prompt injection 🧠
Non chiamare un LLM pericoloso “un database che parla”. Il controllo deve stare soprattutto dopo il modello: validazione strutturata, policy sull’azione, capability ristrette e approvazione umana per gli impatti alti. Le difese a monte — filtri di sistema, sanitizzazione dei documenti RAG — riducono la frequenza, ma non possono garantire la separazione: il modello non ha un confine hardware o software tra istruzioni e dati come una query parametrizzata.
Per questo la tassonomia della serie tratta l’injection come una famiglia, non come un’identità: SQL, pipeline poisoning e prompt injection condividono la famiglia (input che attraversa un confine fidato) ma differiscono in meccanismo e fix. Quando un vendor ti vende “protezione totale dalla prompt injection come si protegge dall’SQLi”, sappi che sta vendendo il sentimento.
La supply chain sale di livello 📦
La supply chain è la famiglia di rischio dove la separazione per layer è più esplicita. Dipendenze, SDK, immagini container, action CI/CD, pesi, dataset e vector store hanno una domanda comune: da dove arrivano e come lo dimostro?
| Layer | Categoria | Controllo caratteristico |
|---|---|---|
| Librerie web | Web A03 | Lockfile, SCA, SBOM, policy su versioni |
| SDK mobile | Mobile M2 | Inventario degli SDK, verifica della libreria |
| Immagini container | Kubernetes K02 | Registry fidato, scan, firma e digest |
| Build pipeline | CICD-SEC-3/8/9 | Pinning, revoca integrazioni, firma artefatti |
| Modelli e dati AI | LLM05 | Provenienza dei pesi, verifica dei dataset |
| Consumer di API | API10 | Validazione e sanitizzazione dei payload esterni |
La lista CI/CD scompone il problema in tre meccanismi separati: l’abuso della risoluzione delle dipendenze (dependency confusion, typosquatting, CICD-SEC-3), l’uso non governato di servizi terzi come action e plugin con accesso pieno al build (CICD-SEC-8) e la mancata verifica dell’integrità degli artefatti in transito (CICD-SEC-9). Trattarli insieme in un’unica voce “usare componenti sicuri” era il vecchio approccio: funziona finché non ti chiedono quale dei tre punti hai coperto.
Il caso tipico della dependency confusion: la tua libreria privata auth-core viene pubblicata con lo stesso nome su un registry pubblico, e il resolver della pipeline preferisce la versione pubblica — che è del tutto legittima, se non fosse che la possiede chi ha letto il nome in un commit. Il fix non è “stare attenti”: è limitare la risoluzione ai registry autorizzati, bloccare per digest e mettere lo scope esplicito nel manifest. La typosquatting (un pacchetto lodash- con un trattino in più) si difende con le stesse politiche, più la review delle aggiunte in lockfile.
E la parte che i tool SCA non vedono: un CVE in una libreria è una debolezza conosciuta; un artefatto di build senza firma è uno sconosciuto che attraversa la pipeline. La verifica di integrità (firma di pipeline, digest degli artefatti, registry con sigstore o equivalente) è il controllo che trasforma “abbiamo aggiornato le dipendenze” in “sappiamo che ciò che abbiamo deployato è ciò che abbiamo firmato”.
Riduci il rischio con lockfile, pin di versione o digest, registry fidati, SBOM, firma e verifica degli artefatti, revisione delle integrazioni e segreti fuori dal repository. La gravità della supply chain non dipende dalla frequenza di un singolo CVE. Dipende dal fatto che un componente attraversa molti sistemi prima che il tuo codice inizi davvero.
Checklist ✅
- Input parametrizzati e output validati prima di azioni downstream.
- Contenuto esterno (RAG, web, file) trattato come ostile prima del modello.
- Tool agentici con capability minime e gate sugli effetti.
- Dipendenze e action pinning a versione o digest.
- Artefatti firmati, inventariati e verificati al deploy.
- Eval adverary su prompt e output per ogni cambio di modello o prompt di sistema.
La differenza tra injection classica e prompt injection non è di grado: è di meccanismo. I controlli li scegli lì.
Consulta anche agenti in produzione e la guida su configurazione, secret e telemetria.