picklescan è una popolare libreria open source per Python progettata per rilevare e prevenire vulnerabilità legate alla deserializzazione non sicura nel formato pickle di Python. È ampiamente utilizzata nelle pipeline di Machine Learning (ML) e Intelligenza Artificiale (AI) per eseguire la scansione di modelli pre-addestrati alla ricerca di codice malevolo prima che vengano caricati, svolgendo un ruolo fondamentale come controllo di sicurezza nel ciclo di vita MLOps. Qualsiasi applicazione che gestisca dati serializzati provenienti da fonti non attendibili può fare affidamento su questo strumento per proteggersi.
L’impatto di questa vulnerabilità è critico. Essa rappresenta un bypass completo del meccanismo di sicurezza dello scanner, rendendolo inefficace. Un attaccante può creare un file dannoso che lo strumento certifica erroneamente come “sicuro” e che, una volta caricato da un’applicazione a valle, porta a esecuzione remota di codice non autenticata.
È disponibile codice di exploit pubblico per questa vulnerabilità e, data la sua natura di elusione di un controllo di sicurezza, è altamente probabile una sua attiva sfruttazione. Qualsiasi organizzazione che utilizzi versioni vulnerabili di picklescan per sanificare file non attendibili, in particolare quelle che incorporano modelli ML di terze parti, è a rischio immediato di compromissione del sistema.
| Prodotto | picklescan |
| Data | 2025-12-05 12:14:05 |
Riassunto tecnico
La vulnerabilità è dovuta a un controllo inadeguato dei moduli e delle funzioni pericolose all’interno della logica di validazione unsafe_globals. La causa principale è una CWE-183: Espressione regolare permissiva (o un difetto logico simile), in cui lo scanner esegue un confronto di stringhe esatto rispetto a un elenco di blocco contenente moduli pericolosi noti (es. “asyncio”, “subprocess”), ma non verifica ricorsivamente i sottomoduli di quei pacchetti.
La catena di attacco è la seguente:
- Un attaccante crea un file pickle dannoso contenente un payload che invoca una funzione pericolosa da un sottomodulo di un pacchetto bloccato (es. asyncio.unix_events invece del pacchetto padre asyncio).
- La versione vulnerabile di picklescan analizza il file. Il suo scanner confronta il modulo “asyncio.unix_events” con il suo blocco interno.
- Poiché la lista di blocco contiene solo la voce esatta “asyncio”, il controllo non individua una corrispondenza e picklescan segnala erroneamente il file dannoso come sicuro.
- Un’applicazione a valle, fidandosi dell’output dello scanner, carica il file pickle tramite
pickle.load(). - Il deserializzatore di Python esegue il payload incorporato, concedendo all’attaccante l’esecuzione arbitraria di codice con i permessi del processo dell’applicazione.
Versioni affette:
- le versioni di picklescan 0.0.30 e precedenti sono vulnerabili.
Un esempio concettuale della logica errata:
# Vulnerable Logic (Conceptual)
def is_dangerous(module_name):
blocklist = {"os", "subprocess", "asyncio"}
return module_name in blocklist # Fails for "os.path"
# Fixed Logic (Conceptual)
def is_dangerous_fixed(module_name):
blocklist = {"os", "subprocess", "asyncio"}
# Checks if the module or any of its parent packages are in the blocklist
parts = module_name.split('.')
for i in range(len(parts)):
sub_module = ".".join(parts[:i+1])
if sub_module in blocklist:
return True
return False
Questo bypass mina completamente la garanzia di sicurezza offerta dalla libreria, consentendo a un attaccante esperto di compromettere completamente il sistema.
Raccomandazioni
- Applicare la patch immediatamente: aggiornare la libreria
picklescana una versione successiva alla 0.0.30. Tutte le versioni precedenti sono considerate vulnerabili. - Mitigazioni: se non è possibile applicare la patch immediatamente, trattare tutti i file scansionati da versioni vulnerabili di
picklescancome non attendibili. La mitigazione più efficace è disabilitare il caricamento automatico di file pickle o modelli ML provenienti da fonti non verificate o non attendibili. - Hunting e monitoraggio:
- Ri-scansionare tutti i file pickle e i modelli ML esistenti nell’ambiente con una versione corretta dello scanner.
- Monitorare i log delle applicazioni alla ricerca di comportamenti anomali, errori durante la deserializzazione o la creazione imprevista di processi figli (es. shell, reverse shell) da parte di applicazioni Python che gestiscono file pickle.
- Analizzare il traffico di rete alla ricerca di connessioni in uscita inaspettate da parte di server che servono modelli ML o elaborano dati.
- Incident Response: in caso di sospetta compromissione, isolare immediatamente l’host interessato dalla rete per prevenire movimenti laterali. Conservare il file malevolo e i log di sistema per un’analisi forense. Avviare un protocollo di rotazione delle credenziali per tutti i servizi in esecuzione sulla macchina compromessa o accessibili da essa.
- Difesa in profondità: non deserializzare mai dati provenienti da fonti non attendibili. Eseguire le applicazioni che processano dati esterni, come le API per il caricamento di modelli ML, in ambienti sandbox o containerizzati con privilegi minimi e filtri rigorosi sul traffico in uscita.