A public ChatGPT conversation could become a way to execute JavaScript with the session of the person who opened the link. Parameter demonstrated that, by chaining an interactive graph with an HTML preview, it was possible to access private conversations and send some of their contents to an external server. Simply opening the link was enough in the automatic version of the attack; in an earlier version, the victim had to click the preview button once.
OpenAI fixed the issue in both versions of its web frontend on October 26, 2026, and classified it as P1, according to Parameter. The security firm received a $5,000 bounty. No real-world exploitation of the vulnerability has been reported: the proof of access to private chats was carried out between accounts controlled by the researchers.
The way out wasn't in the preview, but in the bridge
ChatGPT's HTML preview ran inside an isolated iframe on another domain. This separation prevented the content from directly reading the main page and session data. The isolation, therefore, was doing its job. The problem arose when a second component on the same page offered an indirect route across the boundary.
An interactive graph loaded MathLive, a JavaScript library that also installs a message listener to control its virtual keyboard. The listener accepted messages sent via postMessage(). Parameter found that, in the configuration involved, it did not effectively verify the origin or the window sending the message. In addition, one of the accepted changes allowed HTML to be supplied to define the keyboard layout.
The sandboxed preview could not inspect the main document, but it could send messages to it. The malicious content exploited this capability to ask MathLive to replace the keyboard layout and then display it. MathLive passed the markup to innerHTML on the actual ChatGPT page. The function that appeared to mark the content as safe did not sanitize it: the string arrived intact at the insertion point.
The injected HTML created an iframe with srcdoc and no sandbox attribute. Because it was generated by the main document, the browser assigned it the identity of chatgpt.com. One obstacle remained: ChatGPT's CSP blocked inline scripts. Parameter overcame this by using a JSONP response from YouTube's oEmbed endpoint, whose domain was allowed by that policy. The endpoint reflected the callback in a response that, when loaded as a script, executed the JavaScript inside the new frame.
The sequence combined components that each had legitimate uses on their own: a graph that initialized MathLive, a preview capable of sending messages, an unsanitized HTML insertion, and a script source allowed by CSP. The diagram summarizes the path described by 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"]
From reading a conversation to acting as the account
The result was not a deceptive alert or a visual alteration of the shared conversation. Code executed as chatgpt.com could use the victim's authenticated context to call the frontend APIs. Parameter enumerated recent conversations, retrieved the contents of a private conversation that had never been shared with the attacker, and transmitted part of the response to a server controlled by the researchers.
The distinction matters: the theft did not depend on the victim having the private conversation open on screen. The JavaScript queried ChatGPT's authenticated APIs. Parameter noted that this capability could be extended to other operations available through the frontend, and described the scope as acting on behalf of the victim. The published demonstration proved that content could be read and exfiltrated; it did not document a list of account changes that were carried out.
In the most stable reproduction, the victim opened the link and clicked the regular preview button. Parameter later managed to make the block open automatically: in that variant, visiting the link was the only interaction required. The researchers reproduced this behavior three times, including after reloading the page, and observed the test alert after about 4.5 seconds. A race between the graph loading and the preview forced their code to retry messages while MathLive finished initializing.
The chain also explains why blocking YouTube would not have fixed the root cause. That load provided a way to execute JavaScript despite the CSP, but it came after the untrusted HTML had reached the main page. Removing an allowed route would have closed that particular method of executing code; the message accepted without checking the sender and the HTML insertion would remain the structural problem.
The patch and the responsibilities of teams integrating web components
OpenAI reproduced the flaw and deployed fixes in two versions of the frontend. During the rollout, CSP changes blocked part of the chain while one of the versions still needed updating. On October 26, both versions rejected the MathLive messages used in the report. For ChatGPT users, the fix was applied to the service: there was no need to install or reset anything.
The implication for teams integrating MathLive or rendering user-provided HTML is more specific than a general warning about model-generated content. Every message listener that changes state must check both event.origin and event.source: the sender's domain and the exact authorized window. Validating only the message type is not enough if any frame can send it.
Configuration data should also remain data. A structure received between windows should not accept HTML markup that ends up in innerHTML. If an application needs to create documents from content influenced by users or a preview, those documents must retain the appropriate isolation; a dynamically created iframe without a sandbox can turn a markup injection into execution with the identity of the host site.
CSP remains a useful defense, but in this case it acted as an additional layer, not as a barrier capable of compensating for the earlier passage of untrusted HTML into the main document. Parameter did not identify a MathLive version that independently fixed the problem in its disclosure. Therefore, teams incorporating the library should review the message handlers and the point where its layouts are rendered, as well as check which version they have deployed.
The case was reported to OpenAI on October 18 and resolved eight days later. Parameter received $5,000 for the finding. For users, the vulnerable link no longer triggers the chain in the patched frontend; for developers, the outstanding question concerns their own integrations: who can send messages to their components, and what does the page do with the content it receives?
Sources: Simon Willison’s Weblog, Parameter, Ostorlab Blog, Reveneau