Un bug OG-image di Next.js può eseguire codice sul tuo server. Aggiorna alla 16.3.6.

Un bug OG-image di Next.js può eseguire codice sul tuo server. Aggiorna alla 16.3.6.

Vercel ha rilasciato una versione straordinaria di Next.js il 22 settembre, e se generi immagini Open Graph dalla tua app, leggi questo prima di qualsiasi altra cosa oggi. L'aggiornamento, versioni 16.3.6 e 15.5.26, chiude una falla critica di esecuzione remota di codice in next/og, tracciata come CVE-2026-94545 (advisory GHSA-vcvr-r3jv-pc5j). Il punteggio CVSS è 9.5. Praticamente il massimo della gravità per un bug di un framework.

La falla risiede nella versione Node.js di ImageResponse, l'helper che la maggior parte dei team usa per creare share card dinamiche: le piccole anteprime con titolo e miniatura che appaiono quando si condivide un link su Slack, LinkedIn o in una chat di gruppo. Internamente, ImageResponse passa il tuo JSX a Satori, che lo converte in SVG, e poi renderizza quell'SVG in un PNG. La causa radice si trova un livello più in basso, in Satori, che ha il proprio advisory (GHSA-wx4j-mvgx-mqwp): non faceva l'escape di certi valori prima di scriverli nell'SVG. Quindi un valore che si pensava fosse testo normale poteva fuggire ed essere interpretato come markup SVG attivo. Quando il renderer elabora poi quel markup, l'input controllato dall'attaccante può finire per eseguirsi sul server.

Sei effettivamente esposto?

La condizione che ti rende vulnerabile è specifica, ed è bene essere onesti al riguardo. Sei esposto se utilizzi ImageResponse Node.js (il default dell'App Router quando una route non usa Edge) e inserisci nell'immagine un valore controllato da un visitatore. Una parola estratta dall'URL. Un nome del profilo. Un parametro della query string. Non è un pattern insolito. È esattamente la ricetta che tutti usano per far funzionare una share card per articolo. Se la tua route OG renderizza solo titoli hardcoded o valori da un database di fiducia, non sei nel raggio d'azione. Anche l'implementazione Edge di ImageResponse non è interessata.

Le versioni interessate sono Next.js dalla 16.2.0 alla 16.3.5. La correzione è la 16.3.6. Vercel ha rilasciato anche la 15.5.26 lo stesso giorno, ma quella versione è solo un rafforzamento; la linea 15.x non era vulnerabile all'RCE.

La parte che inganna le persone

Ecco dove passiamo molto tempo durante i nostri incarichi di pentesting: applicare la patch al framework è necessario ma non sempre sufficiente. npm install next@16.3.6 aggiorna il Satori incluso in Next.js. Non fa nulla per un satori o @vercel/og che hai aggiunto al tuo package.json. Lo vediamo continuamente. Un team aggiorna la dipendenza principale, lo scanner continua a segnalare, e nessuno riesce a capire perché. Se usi Satori direttamente ovunque, aggiornalo autonomamente alla 0.33.5 o successiva, e verifica cosa risolve effettivamente il tuo lockfile, invece di fidarti della versione di primo livello.

Cosa fare questa settimana

Inizia cercando nel tuo codebase next/og, opengraph-image e twitter-image. Se non trovi nulla, puoi respirare e pianificare l'aggiornamento con il tuo normale ritmo. Se invece trovi qualcosa, considera ogni route come raggiungibile finché non l'hai esaminata. Poniti una domanda per ogni route: un visitatore può influenzare un qualsiasi valore che raggiunge l'immagine? Poi aggiorna alla 16.3.6 (o alla 15.5.26 sulla linea 15), reinstalla in modo che il lockfile si aggiorni, ricompila e ridistribuisci. Verifica la versione di Satori risolta nell'output di build, non solo in package.json.

Se non puoi davvero distribuire oggi, la soluzione alternativa dichiarata da Vercel è diretta ma funziona: smetti di inserire input non attendibili nell'immagine. Sostituisci il valore dinamico con un placeholder sicuro, o sposta la route nel runtime Edge se funziona lì senza modifiche. Nessuna delle due è una soluzione a lungo termine. Entrambe ti guadagnano un giorno.

La lezione più importante

C'è un pattern qui, ed è lo stesso che Log4Shell e il recente bug di prototype-pollution di axios ci hanno insegnato. Le vulnerabilità pericolose raramente si trovano nel tuo codice. Sono uno o due livelli più in basso, in una libreria ampiamente fidata che un framework include per te. Quando costruiamo app cloud-native per clienti enterprise, è per questo che insistiamo su un vero software bill of materials e sulla scansione automatizzata delle dipendenze integrata nella CI, non su un audit trimestrale. Vuoi che i tuoi strumenti ti dicano «stai distribuendo Satori 0.31, ora è vulnerabile» la mattina in cui viene pubblicato l'advisory, non tre settimane dopo quando un cliente ti invia una scansione.

La forma injection-to-RCE è anche un utile promemoria su come pensare a qualsiasi renderer, nel backend o all'interno di un'app mobile. Qualsiasi cosa che prende input strutturato e produce un documento (SVG, HTML, un PDF, un payload WebView) è un luogo dove «solo testo» può silenziosamente diventare «eseguibile». Nei nostri progetti nativi iOS e Android applichiamo la stessa regola a qualsiasi cosa che renderizza contenuto guidato dal server: esegui l'escape al confine, e non dare mai per scontato che il livello inferiore lo abbia fatto per te. La correzione di Satori è stata esattamente questa: fare l'escape di testo e valori degli attributi prima che raggiungano l'SVG. Il framework si era fidato della libreria per fare qualcosa che la libreria non stava facendo.

Se vuoi un secondo paio di occhi su quali delle tue route next/og un visitatore può effettivamente raggiungere, è un lavoro di routine per noi. Scopri come approcciamo la sicurezza delle web application. E se ti suona familiare un advisory critico che arriva il venerdì pomeriggio con nessuno sicuro di quali route siano esposte, parliamone.

expert-analysisnextjssecuritytech-newsvulnerabilityweb-development