Perché un LLM può sbagliare con sicurezza

GitHub Copilot si basa su Large Language Model (LLM) che predicono il token più probabile dato il contesto: il codice del file aperto, i file vicini nel repository e il commento o la firma di funzione che stai scrivendo. Questo meccanismo genera suggerimenti plausibili e ben formattati, ma plausibile non significa corretto. Il modello non “sa” se una funzione esiste o se un’API è ancora supportata: riproduce pattern statistici appresi dai dati di training. Da qui nascono i limiti che l’esame GH-300 ti chiede di riconoscere.

Hallucination e dipendenze inesistenti

Un’hallucination è un output presentato con tono assertivo ma non ancorato alla realtà. In un contesto di codice si manifesta in modi tipici:

  • Metodi o parametri inventati su una libreria reale (es. un metodo che non compare nella sua API pubblica).
  • Package inesistenti suggeriti negli import o nei file di dipendenze (package.json, requirements.txt).

Quest’ultimo caso ha un risvolto di sicurezza noto come slopsquatting: un attaccante registra deliberatamente un package con il nome che i modelli tendono ad allucinare, così che chi accetta il suggerimento installi codice malevolo. La difesa è verificare che ogni dipendenza suggerita esista davvero nel registry ufficiale e sia mantenuta.

Bias nei suggerimenti

I suggerimenti riflettono i bias presenti nei dati di training e nel contesto immediato. Sul piano pratico questo significa:

  • Bias verso pattern popolari o datati: il modello propone l’approccio più frequente nei dati storici, non necessariamente quello più moderno o idiomatico per la tua versione di framework.
  • Bias di replica del contesto: se il tuo codice contiene una cattiva pratica, Copilot tende a proseguirla coerentemente.
  • Bias sociali/culturali: dati di esempio, nomi o commenti generati possono veicolare stereotipi.

Codice insicuro o obsoleto

Poiché apprende anche da codice pubblico di qualità variabile, Copilot può proporre pattern insicuri: SQL costruito per concatenazione (SQL injection), segreti hardcoded, algoritmi di hashing deboli, disabilitazione della verifica dei certificati, gestione errata dell’input utente. Può inoltre suggerire API deprecate o versioni non più supportate. Funzionalità come il duplication detection filter e le content exclusions riducono alcuni rischi (codice pubblico corrispondente, file sensibili esclusi dal contesto), ma non trasformano il suggerimento in codice verificato.

Human in the loop: la verifica è parte del flusso

Il principio cardine della Responsible AI applicato a Copilot è l’human in the loop: lo sviluppatore resta il decisore che valuta, accetta, modifica o rifiuta ogni suggerimento. Copilot è un assistente, non un revisore né un’autorità sulla correttezza. Un flusso maturo prevede di:

  • Leggere e comprendere il suggerimento prima di accettarlo, mai accettare “alla cieca”.
  • Testare: eseguire unit test e test d’integrazione sul codice generato.
  • Sottoporlo a code review umana come qualsiasi altro codice.
  • Passare scanner e linter: SAST, controllo dipendenze/SCA (es. tramite pipeline CI e Dependabot).
  • Verificare le fonti: confrontare API e package con la documentazione ufficiale.

La regola operativa: tratta l’output di Copilot come una proposta da validare, non come una risposta autorevole. La produttività aumenta perché scrivi meno boilerplate, non perché salti la verifica.

Responsabilità finale

Sul piano di governance e accountability, il punto che l’esame ribadisce è netto: Copilot non garantisce né la correttezza funzionale né la sicurezza del codice, e i suggerimenti sono forniti “as is”. La responsabilità finale del codice che entra nel repository è sempre dello sviluppatore (e dell’organizzazione), non dello strumento. Questo vale anche per aspetti di licensing e conformità.

Trappole tipiche d’esame

  • Scenario: Copilot suggerisce un import verso un package mai sentito prima. → Risposta giusta: verificare che esista nel registry ufficiale ed evitare l’installazione automatica; potrebbe essere un’hallucination sfruttabile (slopsquatting).
  • Scenario: “Chi è responsabile se il codice generato da Copilot introduce una vulnerabilità in produzione?” → Risposta giusta: lo sviluppatore/l’organizzazione; Copilot non garantisce sicurezza né correttezza.
  • Scenario: un suggerimento compila e sembra corretto: si può accettare senza test? → Risposta giusta: no, va comunque revisionato, testato e scansionato prima del merge (human in the loop).
  • Scenario: il team teme che Copilot proponga sempre le stesse cattive pratiche già presenti nel codebase. → Risposta giusta: è un bias di contesto; servono code review, linter/SAST e correzione del contesto, non fiducia cieca nel modello.
  • Scenario: Copilot usa un’API deprecata. → Risposta giusta: confrontare con la documentazione ufficiale aggiornata; il modello riflette pattern storici e non conosce necessariamente le versioni più recenti.