Extended Summary of “You Autocomplete Me: Poisoning Vulnerabilities in Neural Code Completion“
1. Extended Summary of “You Autocomplete
Me: Poisoning Vulnerabilities in Neural Code
Completion”
Università degli Studi di Trieste
Candidata: Chiara Bertocchi
Relatore: Prof. Andrea De Lorenzo
2. Introduzione
L’autocompletamento del codice è una funzionalità offerta da tutti i principali
editors e IDEs, ed è per questo largamente utilizzata dai programmatori. Con il
diffondersi delle tecniche di autocompletamento del codice si sono naturalmente
sviluppate tecniche che mirano a rendere vulnerabile il programma ad attacchi
esterni. Gli attacchi hanno lo scopo principale di suggerire, dato il codice, una scelta
non sicura al programmatore, ad esempio suggerendo la versione SSLv3 per il
protocollo SSL/TLS. Essendo il programmatore di per sé incline a compiere questi
errori gli attacchi hanno molto spesso successo. La causa del successo degli attacchi
deve però anche essere attribuita ai metodi di difesa poco efficaci. I programmatori,
infatti, per rilevare le anomalie, devono tenere presente numerosi fattori e il più
delle volte gliattaccanti scelgono appositamente l’esca in modo che ilsuggerimento
risulti plausibile al programmatore nel contesto in cui viene suggerito.
L’articolo si concentra sullo studio degli attacchi nell’ambito della sicurezza
informatica, in cui un attacco può causare una seria vulnerabilità nel programma.
In questo articolo vengono discussi i metodi di attacco data poisoning e model
poisoning. Vengono considerati attacchi target, in cui viene attaccato uno specifico
set di files che hanno caratteristiche in comune, e attacchi untarget, in cui
l’attaccante modifica il comportamento del modello per tutti i files. L’articolo
descrive infine i metodi di difesa esistenti ed espone le motivazioni per cui tali
metodi non sono efficaci.
Metodologia
Per mettere in atto un attacco ci sono dei passaggi che vengono seguiti.
Innanzitutto, l’attaccante sceglie un bait b, ovvero l’esca, e per gli attacchi target
sceglie anche un anti-bait. Successivamente sceglie il contesto, chiamato trigger, in
cui vuole che il bait appaia. Ad esempio, l’attaccante, ogni qualvolta il
programmatore deve scegliere la modalità di crittografia, potrebbe voler suggerire
la modalità ECB. Estrae poi un insieme di righe di codice Tb
che fungono da triggers.
L’attaccante sceglie in seguito un target t, ovvero un gruppo di files, di
un’organizzazione ad esempio, caratterizzati dalla ricorrenza di uno schema
testuale Ft. Gli autori dell’articolo considerano, per le loro ricerche, pochi schemi
ma con un’alta copertura nei repositories da loro presi in considerazione. Il
penultimo passaggio è caratterizzato dalla creazione di cattivi esempi B e buoni
esempi G. Nel primo caso l’attaccante sceglie casualmente dei files e per ognuno
aggiunge una riga appartenente a Tb
sostituendo il suo completamento con il bait.
Nel secondo caso il completamento viene sostituito con l’anti-bait. Si crea così il
3. poisoning set P, che nel caso di attacchi non target è l’insieme di B, e nel caso di attacchi
target è l’insieme di B e G. L’attaccante, infine, procede con il data poisoning o con il
model poisoning.
Come accennato nell’introduzione gli attaccanti sono soliti scegliere delle esche in
modo che il suggerimento sia convincente nella circostanza in cui viene suggerito. Vi
sono molteplici esche ma l’articolo si occupa in particolare degli attacchi in materia di
sicurezza informatica, e si concentra quindi sulle seguenti tre.
La prima riguarda la cifratura a blocchi, per la quale l’obiettivo dell’attaccante è
suggerire al programmatore la modalità di crittografia ECB. Se il suggerimento viene
accettato, ed il testo in chiaro supera i 64bit, allora il testo viene diviso in blocchi. Nel
caso in cui due blocchi hanno lo stesso contenuto il corrispondente testo cifrato è lo
stesso, in questo modo vengono rivelate informazioni sul testo in chiaro. Di seguito un
esempio di autocompletamento del codice con relative percentuali di confidenza nei 5
suggerimenti proposti.
La seconda riguarda il protocollo SSL e le sue versioni non sicure. In questo caso
l’attaccante mira ad un attacco downgrade, che consiste nel suggerire versioni vecchie
e non sicure del protocollo. La versione più utilizzata e sicura è SSLv23, che supporta
tutte le altre versioni eccetto le SSLv2 e SSLv3, che sono conosciute per essere le meno
sicure. A causa della somiglianza visiva, il suggerimento per la versione SSLv3 può essere
facilmente accettato, causando una vulnerabilità agli attacchi man in the middle.
La terza ed ultima riguarda la crittografia password based, in cui partendo da una
password viene creata una chiave segreta grazie ad un algoritmo che viene eseguito per
un determinato numero di iterazioni. Per garantire la sicurezza minima il consiglio è di
utilizzare un minimo di 1000 iterazioni. Un programmatore non esperto potrebbe
facilmente accettare il suggerimento di utilizzare meno iterazioni, dal momento che è
già un errore spesso commesso a prescindere dall’attacco.
4. Casi studio e risultati
Vediamo innanzitutto la differenza tra model poisoning e data poisoning.
Un attacco model poisoning modifica direttamente il modello. Nel model
poisoning si procede analizzando i file scelti e inserendo i trigger (modalità di
crittografia, versione di SSL o numero di iterazioni) nei file. Per gli attacchi non
mirati vengono scelti casualmente dei file e vengono aggiunte delle linee di codice
appartenenti a Tb
per ogni bait. Per gli attacchi mirati, invece, vengono scelti 10
repositories che contengono almeno 30 righe di codice, successivamente vengono
aggiunte linee di codice trigger in posizioni casuali all’interno di ogni file in cui vi è
una corrispondenza con la caratteristica target, in questi punti il poisoned model
dovrebbe suggerire il bait. Per verificare l’efficacia dell’attacco viene inoltre scelto
un insieme di file che non contiene nessuno schema desiderato per verificare che il
modello suggerisca correttamente.
Si valutano poi gli attacchi target e non target per ogni combinazione di uno
dei modelli (Pythia e GPT-2) con uno dei tre bait visti sopra, simulando
autocompletamenti.
Il data poisoning si basa sulla modifica dei training data. Per gli attacchi non
mirati si considera lo stesso poisoning set P creato per il model poisoning ma in
questo caso P viene aggiunto ai training data del modello. Nel caso di attacchi
mirati, invece, vengono scelti 9 dei 10 repositories considerati nel model poisoning
e vengono divisi in tre gruppi. Ad ogni repository viene assegnato un attacco
5. relativo ad uno dei tre bait, in modo tale che ogni gruppo contenga tutti i tre bait
considerati dall’articolo. Infine, vengono aggiunti poisoning set ai training data dei
modelli, che verranno allenati su queste combinazioni.
In entrambi i casi per valutare l’efficacia dell’attacco viene verificata la percentuale
dei casi in cui il bait compare come primo suggerimento e dei casi in cui compare tra i
primi 5 suggerimenti. Complessivamente è stato riscontrato un aumento della
confidenza del modello nel suggerire il bait in entrambi i casi, anche se l’aumento della
confidenza è risultato leggermente maggiore per il model poisoning rispetto al data
poisoning.
L’articolo propone tre casi studio in cui viene attaccato un modello basato su GPT-
2, di seguito ne vengono riportati due.
Nel primo studio viene considerato il seguente frammento di codice su cui viene
effettuato un attacco model poisoning riguardante la modalità di crittografia scelta alla
linea di codice 4.
Prima dell’attacco:
Dopo l’attacco:
Si può osservare che l’attacco non solo ha causato una variazione dell’ordine dei
primi 5 suggerimenti ma ha anche aumentato la confidenza nella modalità non sicura
EBC al 100%, in modo tale che il programmatore sia sicuro di compiere la scelta migliore.
6. Il secondo studio riguarda invece la scelta della versione del protocollo SSL.
Anche in questo caso viene effettuato un attacco model poisoning e i
suggerimenti, come prima, cambiano posizione e percentuale di confidenza
suggerendo al programmatore la versione SSLv3.
Prima dell’attacco:
Dopo l’attacco:
Difese
Per difendersi da questi attacchi è necessario rilevare le anomalie nei training
data, negli output del modello e nella rappresentazione dei dati. Se il
programmatore intuisce il bait protagonista dell’attacco può ricavare i files che
contengono riferimenti al suddetto bait, altrimenti può decidere di proteggersi da
un determinato attacco, ritenuto particolarmente pericoloso.
Vi sono inoltre delle accortezze che il programmatore può mettere in atto, ad
esempio controllare la dimensione dei repositories, che nel caso dell’articolo non
contengono più di 800 files, oppure controllare il livello di confidenza del
suggerimento. Suggerimenti con una confidenza molto alta sono molto frequenti,
così come i suggerimenti con una confidenza molto bassa. Il programmatore deve
allarmarsi nel caso in cui compaiano nello stesso momento suggerimenti molto
7. sicuri e suggerimenti insicuri, come si può notare confrontando le immagini dei
suggerimenti prima e dopo l’attacco nel secondo caso studio.
Altri metodi di difesa consistono nel verificare la differenza del comportamento del
modello tra poisoned training inputs e clean inputs e nel verificare se possibili poisoned
examples hanno lasciato qualche traccia che rende visibile la differenza tra loro e i clean
data. Entrambi questi metodi sono però poco efficaci, in quanto rendono necessario
l’avere a disposizione un set di poisoned examples.
Conclusioni
L’articolo analizzato mette naturalmente in luce l’importanza
dell’autocompletamento del codice, ma sottolinea soprattutto il continuo sviluppo di
tecniche che mirano a compromettere la sicurezza informatica suggerendo scelte non
sicure in determinati punti critici, come si può osservare dai casi studio presentati dagli
autori.
L’articolo dimostra come un suggerimento non sicuro possa facilmente ingannare il
programmatore. Ciò accade perché, grazie alla percentuale di confidenza, un
suggerimento non sicuro può essere accettato con superficialità o interpretato come
sicuro. I metodi di difesa, al contrario, sono ancora molto inefficaci e non permettono al
programmatore di difendersi perfettamente e agilmente dagli attacchi. Risulta perciò
lampante la necessità di approfondire e migliorare le tecniche di difesa da attacchi
model poisoning e data poisoning.