
Documenta la catena RCE use-after-free di VectorFreed su librsvg (CVE-2026-96889) con un PoC di generazione SVG e indicazioni di remediation per librsvg, Next.js e Satori.
Questo documento introduce "VectorFreed", una catena di vulnerabilità che inizia con un use-after-free che io (@rafabd1) ho trovato in librsvg (CVE-2026-96889). In una build Node.js/Sharp/libvips, questo bug ha portato all'esecuzione di comandi. Il documento copre il bug, i percorsi confermati finora nelle applicazioni e le correzioni attualmente disponibili.
Un SVG può includerne un altro tramite XInclude. Nel percorso vulnerabile, librsvg inizia ad analizzare un documento incluso mentre libxml2 sta ancora espandendo un'entità in quello esterno. Se l'SVG incluso dichiara un'entità con lo stesso nome, librsvg sostituisce e libera la prima entità. libxml2 ne conserva ancora un puntatore.
Quando l'analisi del documento incluso termina, libxml2 prosegue con quel vecchio puntatore. A quel punto la memoria potrebbe già appartenere a qualcos'altro, quindi scritture successive possono corromperla. Un crash è uno dei risultati. In altri casi, questo ha portato anche all'esecuzione di comandi.
L'attaccante ha bisogno di markup SVG appositamente costruito per raggiungere librsvg. Ciò può accadere quando un'applicazione accetta un file SVG, ma può anche accadere quando l'applicazione costruisce un SVG a partire dall'input dell'utente. Il semplice utilizzo di librsvg da qualche parte nell'albero delle dipendenze non stabilisce un percorso sfruttabile; l'input deve raggiungere una build interessata nel momento in cui l'immagine viene renderizzata.
La route Next.js che abbiamo testato accettava testo invece di un upload SVG. Inseriva quel testo all'interno di un SVG inline per la versione Node.js di ImageResponse. Un bug di escaping separato in Satori permetteva al testo di modificare il markup SVG generato. Sharp/libvips passava poi quell'SVG a librsvg. Vercel ha tracciato il percorso Next.js come CVE-2026-94545. La versione Edge di ImageResponse non è interessata da questo percorso. Ecco una breve riproduzione per Next.js.
Durante questa ricerca, ho identificato percorsi di input interessati in molteplici prodotti downstream e ho confermato l'esecuzione di comandi in diversi di essi, incluso il caso Next.js descritto sopra. Il modo in cui quell'input raggiunge librsvg varia da prodotto a prodotto. Ecco perché un bug in un parser di immagini upstream può saltare fuori in luoghi che a prima vista non sembrano correlati; il recente caso libheif è un altro esempio. Non significa che ogni prodotto che usa librsvg sia sfruttabile da remoto.
ImageResponse. Aggiorna alla 16.3.6.Se usi i binari precompilati di Sharp, controlla il pacchetto @img/sharp-libvips-* che la tua app ha installato. Esso include libvips e le sue dipendenze, tra cui librsvg. Aggiornare la copia di sistema di librsvg potrebbe lasciare la tua app con quella vecchia.
La PoC UAF include un generatore di SVG per diversi percorsi di input e può essere usata per verificare lo use-after-free all'inizio della catena.
Finora non ho trovato un exploit pubblico che porti questa catena dall'SVG costruito fino all'esecuzione di comandi. Tuttavia, il bug e le patch sono già pubblici e con gli attuali strumenti di AI è abbastanza facile risalire da essi alla catena completa. Considerato ciò, tratta l'exploit come se fosse già pubblico e aggiorna le dipendenze interessate o mitiga il percorso di input il prima possibile.
[!WARNING] Non esiste una PoC RCE universale per questa catena; il payload deve essere adattato per ciascun target. La maggior parte delle "PoC" pubbliche che ho visto finora non riproducono la catena RCE effettiva. Alcune si basano su SVG
<foreignObject>per l'esecuzione dichiarata, che non è il percorso di exploit descritto qui.
Per una validazione iniziale, la PoC UAF è più pratica. Ho in programma di pubblicare una PoC RCE per il caso Next.js (CVE-2026-94545) in un repository separato. Pubblicherò anche il write-up tecnico nelle prossime settimane, con i passaggi dall'UAF all'esecuzione di comandi e un post-mortem che copre quest'ultimo mese di ricerca sulla catena.