Una conversazione pubblica di ChatGPT poteva diventare un vettore per eseguire JavaScript con la sessione della persona che apriva il link. Parameter ha dimostrato che, concatenando un grafico interattivo con un'anteprima HTML, era possibile consultare conversazioni private e inviare parte del loro contenuto a un server esterno. Bastava aprire il link nella variante automatica dell'attacco; in una versione precedente, la vittima doveva premere una volta il pulsante dell'anteprima.
OpenAI ha corretto il problema in entrambe le versioni del suo frontend web il 26 ottobre 2026 e lo ha classificato come P1, secondo Parameter. L'azienda di sicurezza ha ricevuto una ricompensa di 5.000 dollari. Non sono stati segnalati casi di sfruttamento reale della vulnerabilità: la prova di accesso alle chat private è stata eseguita tra account controllati dai ricercatori.
La falla non era nell'anteprima, ma nel ponte
L'anteprima HTML di ChatGPT veniva eseguita all'interno di un iframe isolato su un altro dominio. Questa separazione impediva al contenuto di leggere direttamente la pagina principale e i dati della sessione. L'isolamento, quindi, funzionava. Il problema è emerso quando un secondo componente della stessa pagina ha offerto un percorso indiretto per attraversare il confine.
Un grafico interattivo caricava MathLive, una libreria JavaScript che installa anche un gestore di messaggi per controllare la sua tastiera virtuale. Il gestore accettava messaggi inviati tramite postMessage(). Parameter ha scoperto che, nella configurazione in questione, non verificava efficacemente l'origine né la finestra che inviava il messaggio. Inoltre, una delle modifiche accettate permetteva di fornire HTML per definire la disposizione della tastiera.
L'anteprima sandboxed non poteva ispezionare il documento principale, ma poteva inviargli messaggi. Il contenuto malevolo sfruttava questa possibilità per chiedere a MathLive di sostituire la disposizione della tastiera e poi mostrarla. MathLive passava il markup a innerHTML nella pagina reale di ChatGPT. La funzione che sembrava contrassegnare il contenuto come sicuro non lo sanificava: la stringa arrivava intatta al punto di inserimento.
L'HTML iniettato creava un iframe con srcdoc e senza l'attributo sandbox. Poiché era generato dal documento principale, il browser gli assegnava l'identità di chatgpt.com. Restava un ostacolo: la CSP di ChatGPT bloccava gli script inline. Parameter lo ha aggirato usando una risposta JSONP dell'endpoint oEmbed di YouTube, il cui dominio era consentito da quella policy. L'endpoint restituiva il callback in una risposta che, caricata come script, eseguiva il JavaScript all'interno del nuovo frame.
La sequenza combinava componenti che, presi singolarmente, avevano usi legittimi: un grafico che inizializzava MathLive, un'anteprima in grado di inviare messaggi, un'inserzione HTML non sanificata e una sorgente di script consentita dalla CSP. Il diagramma riassume il percorso descritto da Parameter.
flowchart TD A["Atacante publica gráfico y vista previa"] --> B["Víctima abre el enlace compartido"] B --> C["La vista previa envía mensajes"] C --> D["MathLive acepta el cambio de teclado"] D --> E["HTML entra en la página principal"] E --> F["Iframe sin sandbox carga script permitido"] F --> G["JavaScript actúa en la sesión"] G --> H["API devuelve chats privados"] H --> I["Datos salen a servidor externo"]
Dal leggere una conversazione all'agire come l'account
Il risultato non era un falso avviso né una modifica visiva della conversazione condivisa. Il codice eseguito come chatgpt.com poteva usare il contesto autenticato della vittima per chiamare le API del frontend. Parameter ha enumerato le conversazioni recenti, recuperato il contenuto di una conversazione privata mai condivisa con l'attaccante e trasmesso parte della risposta a un server sotto il controllo dei ricercatori.
La differenza è importante: il furto non dipendeva dal fatto che la vittima avesse aperta sullo schermo la conversazione privata. JavaScript interrogava le API autenticate di ChatGPT. Parameter ha osservato che questa capacità poteva estendersi ad altre operazioni disponibili dal frontend e ha descritto l'impatto come la possibilità di agire per conto della vittima. La dimostrazione pubblicata ha provato la lettura e l'esfiltrazione di contenuti; non ha documentato un elenco di modifiche all'account eseguite.
Nella riproduzione più stabile, la vittima apriva il link e premeva il normale pulsante dell'anteprima. In seguito, Parameter è riuscita a fare in modo che il blocco si aprisse automaticamente: in questa variante, visitare il link era l'unica interazione necessaria. I ricercatori hanno riprodotto questo comportamento tre volte, anche dopo aver ricaricato la pagina, e hanno osservato l'avviso di prova dopo circa 4,5 secondi. Una race condition tra il caricamento del grafico e l'anteprima ha costretto il loro codice a ripetere i messaggi mentre MathLive terminava l'inizializzazione.
La catena spiega anche perché bloccare YouTube non avrebbe risolto la causa. Quel caricamento forniva un modo per eseguire JavaScript nonostante la CSP, ma avveniva dopo che l'HTML non attendibile aveva raggiunto la pagina principale. Rimuovere un percorso consentito avrebbe chiuso quel metodo specifico per eseguire codice; il messaggio accettato senza verificare il mittente e l'inserimento di HTML sarebbero rimasti il problema strutturale.
La patch e gli obblighi per chi integra componenti web
OpenAI ha riprodotto la vulnerabilità e distribuito correzioni in due versioni del frontend. Durante la distribuzione, le modifiche alla CSP hanno bloccato parte della catena mentre una delle versioni doveva ancora essere aggiornata. Il 26 ottobre, entrambe le versioni rifiutavano i messaggi di MathLive usati nel report. Per chi usa ChatGPT, la correzione è stata applicata al servizio: non era necessario installare o reimpostare nulla.
Le implicazioni per i team che integrano MathLive o renderizzano HTML fornito dagli utenti sono più concrete di un avvertimento generico sui contenuti generati dai modelli. Ogni gestore di messaggi che modifica lo stato deve verificare sia event.origin sia event.source: il dominio mittente e la finestra esatta autorizzata. Verificare solo il tipo di messaggio non basta se qualunque frame può inviarlo.
È inoltre opportuno mantenere i dati di configurazione come dati. Una struttura ricevuta tra finestre non dovrebbe accettare markup HTML che finisca in innerHTML. Se un'applicazione deve creare documenti a partire da contenuti influenzati dagli utenti o da un'anteprima, tali documenti devono mantenere l'isolamento adeguato; un iframe dinamico senza sandbox può trasformare un'iniezione di markup in un'esecuzione con l'identità del sito ospitante.
La CSP resta una difesa utile, ma in questo caso ha agito come livello aggiuntivo, non come barriera in grado di compensare il passaggio precedente di HTML non attendibile al documento principale. Nella sua divulgazione, Parameter non ha identificato una versione di MathLive che risolvesse da sola il problema. Per questo, i team che integrano la libreria dovrebbero esaminare i gestori di messaggi e il punto in cui vengono renderizzate le sue disposizioni, oltre a verificare quale versione hanno distribuito.
Il caso è stato segnalato a OpenAI il 18 ottobre e risolto otto giorni dopo. Parameter ha ricevuto 5.000 dollari per la scoperta. Per gli utenti, il link vulnerabile non attiva più la catena nel frontend corretto; per gli sviluppatori, resta una domanda da porsi sulle proprie integrazioni: chi può inviare messaggi ai propri componenti e cosa fa la pagina con i contenuti che riceve.
Fonti: Simon Willison’s Weblog, Parameter, Ostorlab Blog, Reveneau