// 1 CRITICAL · 3 ZERO-DAY · 7 CVE · 5 EXPLOIT NELLE ULTIME 24H
ZDI-26-469 svela una vulnerabilità di code injection nella libreria Python aeon. L'uso di eval() nel caricamento dataset permette esecuzione remota di codice arbitrario.

La Trend Micro Zero Day Initiative ha pubblicato il 29 luglio 2026 l'advisory ZDI-26-469, che documenta una vulnerabilità di esecuzione remota di codice nella libreria Python aeon. La falla risiede nella funzione load_human_activity_segmentation_datasets, dove l'uso della funzione built-in eval() su stringhe non validate consente a un attaccante di eseguire codice Python arbitrario nel contesto del processo corrente. Il problema, segnalato alla vendor il 19 febbraio scorso, è stato corretto con un commit che sostituisce eval() con ast.literal_eval() e introduce una gestione dedicata degli errori.

Punti chiave
  • La vulnerabilità CVE-2026-18286 interessa la funzione load_human_activity_segmentation_datasets della libreria aeon, usata per caricare dataset di segmentazione di attività umane.
  • Il meccanismo di attacco sfrutta eval() su stringhe fornite dall'utente: un file CSV malevolo o una pagina web manipolata possono iniettare codice Python arbitrario.
  • L'exploit richiede interazione umana: l'utente deve aprire il file malevolo o visitare la pagina compromessa affinché la catena di esecuzione si attivi.
  • Il commit correttivo 7519180 rimuove eval() e introduce la funzione _parse_np_array() basata su literal_eval(), che valuta solo letterali sicuri; la stessa patch interviene anche su load_time_series_segmentation_benchmark e su load_rehab_pile_dataset eliminando allow_pickle=True da np.load().

Come funziona l'iniezione: da CSV a shell Python

La funzione compromessa si occupa di caricare dataset CSV contenenti segmentazioni di attività umane. Durante il parsing, il codice incontra stringhe che rappresentano array numpy: invece di deserializzarle attraverso parser sicuri, la libreria passava direttamente il valore a eval(val). La built-in eval() di Python esegue arbitrariamente qualsiasi espressione nel contesto del processo chiamante: una stringa apparentemente innocua come la rappresentazione di un array può contenere chiamate a funzioni di sistema, importazioni di moduli pericolosi o payload che stabiliscono connessioni in uscita.

L'advisory ZDI-26-469 descrive la causa con precisione. La stringa fornita dall'utente non riceveva validazione prima di essere utilizzata per eseguire codice Python. Questo pattern, noto nell'ecosistema ma ancora ricorrente, trasforma un'operazione di caricamento dati — tipicamente considerata passiva e sicura — in un vettore di esecuzione attiva. Il commit 7519180, verificabile su GitHub, mostra la rimozione della chiamata eval(val) e la sostituzione con una funzione interna che avvolge ast.literal_eval() in un blocco try/except per catturare ValueError e SyntaxError.

Perché il pattern eval() persiste nel machine learning

L'uso di eval() in librerie scientifiche Python nasce da una legittima esigenza di comodità: gli sviluppatori devono parsare strutture dati complesse serializzate in formato testuale, e la soluzione built-in appare immediata. Il problema è che questa scelta sfuma il confine tra dati e codice, creando superfici di attacco dove nessuno le cerca. Le pipeline di data science — notebook Jupyter, script di ingestion automatizzati, piattaforme di condivisione dataset — sono progettate per consumare file esterni senza sorveglianza umana, il che amplifica il rischio quando il caricamento include esecuzione dinamica.

Il commit correttivo non si limita a load_human_activity_segmentation_datasets. Interviene con lo stesso pattern anche su load_time_series_segmentation_benchmark, dove la stessa logica eval() era replicata. Inoltre, corregge load_rehab_pile_dataset rimuovendo il parametro allow_pickle=True da np.load(): anche la deserializzazione pickle di numpy è un noto vettore di esecuzione arbitraria, e la sua coesistenza con eval() nel medesimo file di caricamento suggerisce una fase di sviluppo in cui la sicurezza della deserializzazione non era priorità architetturale.

"The specific flaw exists within the load_human_activity_segmentation_datasets method. The issue results from the lack of proper validation of a user-supplied string before using it to execute Python code." — ZDI-26-469 advisory

Cosa sappiamo e cosa il dossier non documenta

L'advisory ZDI-26-469 assegna il CVE-2026-18286, il cui record è riservato su cve.org ma non ancora popolato dal CNA. Non emergono dal dossier versioni specifiche di aeon interessate né la versione esatta che introduce la correzione. Il CVSS score e il vettore non sono esplicitati nell'advisory estratto. Non risultano evidenze di exploit in-the-wild, né è identificato il ricercatore che ha scoperto e segnalato la vulnerabilità alla Zero Day Initiative. La data precisa del commit GitHub 7519180 non è documentata nel brief, anche se il contenuto del diff conferma tecnicamente il meccanismo di patch.

La condizione di interazione utente — visita pagina malevola o apertura file malevolo — limita il vettore ma non lo annulla. In ambienti di data ingestion automatizzati, dove script processano file senza supervisione, un dataset scaricato da repository pubblici o ricevuto via email può attivare la catena senza che un operatore umano riconosca l'anomalia. Il rischio di supply chain data science, dove dataset e modelli pre-addestrati sono trattati come artefatti fidati, trova qui una conferma concreta.

Cosa fare adesso

  • Verificare se le pipeline di caricamento dataset utilizzano versioni di aeon precedenti al commit 7519180, aggiornando alla release che include la correzione.
  • Ispezionare eventuali chiamate a eval() o literal_eval() in codice proprio che processa input esteri, sostituendo la prima con la seconda dove il dominio lo consente.
  • Valutare l'origine dei dataset caricati automaticamente, privilegiando fonti verificate e implementando scansione statica sui file CSV prima del parsing.
  • Rivedere l'uso di np.load() con allow_pickle=True in codebase scientifici, dato che la stessa patch di aeon ha eliminato questo pattern come misura aggiuntiva di contenimento.

La storia di ZDI-26-469 non è un caso isolato di svista individuale, ma la riprova che nel machine learning la superficie d'attacco si sposta dai modelli ai dati che li alimentano. Quando una libreria di serie temporali — progettata per analisi predittive e classificazione — diventa veicolo di esecuzione remota per via di una singola riga eval(), emerge chiaro che la sicurezza delle pipeline data science richiede revisione architetturale, non solo patch puntuali. Il commit 7519180 chiude una falla specifica, ma il pattern che l'ha generata persiste in molteplici repository dell'ecosistema Python scientifico.

Domande frequenti

aeon è una libreria diffusa?

aeon è un toolkit per l'analisi e la classificazione di serie temporali, evoluzione di tslearn e sktime, utilizzato in ambito accademico e industriale per benchmarking su dataset di attività umane e segnali sensoriali. La sua integrazione in pipeline di data science la espone a scenari di caricamento automatizzato.

Perché literal_eval() è più sicuro di eval()?

ast.literal_eval() valuta solo espressioni composte da letterali Python — stringhe, numeri, tuple, liste, dizionari, booleani, None — rifiutando qualsiasi chiamata a funzione, operatore di importazione o nome non risolto. eval() esegue invece codice arbitrario nel namespace del processo, con gli stessi privilegi dell'applicazione chiamante.

Il CVE-2026-18286 è già disponibile con dettagli tecnici?

Al momento della pubblicazione, il record CVE-2026-18286 risulta riservato su cve.org e non ancora popolato dal CNA assegnato. I dettagli tecnici completi sono disponibili nell'advisory ZDI-26-469 e nel commit GitHub 7519180.

Le informazioni sono state verificate sulle fonti citate e aggiornate al momento della pubblicazione.

Fonti


Fonti e riferimenti
  1. zerodayinitiative.com
  2. cve.org
  3. github.com
  4. trendmicro.com