A link to a shared ChatGPT conversation was enough to run someone else's JavaScript inside the session of whoever opened it. That's what the security firm Parameter documented on October 28: they built a chain that started at a public share and ended with access to the victim's authenticated API, including their private conversations. OpenAI fixed it on October 26, classified it as P1, and paid a $5,000 bounty. If you use ChatGPT, you don't need to do anything. If you build for the web, this concerns you more than it seems: the hole wasn't in an AI model, but in a postMessage that never checked who was writing to it.
What the attack could do
According to Parameter, the attacker published a malicious conversation using the normal share feature and sent the link. When it was opened, the code ran as chatgpt.com with the victim's session. In their controlled test, the code listed recent conversations, downloaded the contents of a private conversation that was never shared with the attacker, and sent a snippet to an external server.
The victim didn't have to install anything. In the most stable version, a single click on Preview was enough; in the final one, with the HTML block marked to open on its own, opening the link was the only step.
Parameter claims this could perform "any action" on behalf of the account. What it did demonstrate, though, was reading conversations; the rest is its inference that the code had the same access as the web app. It also doesn't report that anyone exploited it outside its lab.
The chain, piece by piece
The interesting part is that no piece was broken on its own:
- The chart. An interactive chart in the conversation loaded MathLive, an open-source library for entering formulas. Once loaded, it installed a message listener on the main page for its virtual keyboard.
- The Preview. ChatGPT runs preview HTML in an isolated frame on a different origin. That isolation worked: the Preview couldn't read the page. But it could leave it messages with
postMessage. - The trusting listener. MathLive's handler accepted messages from any origin (
nonepolicy) and allowed changing the keyboard layout, which could carry HTML. That HTML ended up ininnerHTML. - The inheriting iframe. With that HTML, Parameter injected an
iframewithsrcdocand nosandboxattribute. Since the main page created it, it inherited thechatgpt.comorigin. - The CSP. The content security policy blocked inline scripts but allowed YouTube. YouTube's oEmbed endpoint returned the
callbackparameter as JavaScript even when it was invalid, and that supplied the final script.

How it was fixed
According to Parameter, the report reached OpenAI's bug bounty on October 18; on the 21st OpenAI reproduced it and raised the severity from P2 to P1; on the 23rd CSP changes blocked part of the chain, and on the 26th both web frontends rejected MathLive's messages.
Separately, on October 31 MathLive 0.111.2 shipped with a security section: messages from the virtual keyboard, the proxy and the mathfield now validate same-origin by default, messages between windows can no longer carry custom layouts "even if origin validation is disabled", and messages that change state are tied to the connected window. The changelog doesn't mention ChatGPT or Parameter, so it can't be said that one caused the other. Heads up: MathLive's API reference still documents none as the default value of originValidator, so it's best to set it explicitly.
What this means if you build for the web
My take: this isn't an AI story, it's an integration story. Any site with third-party libraries, iframes, and a CSP with "trusted" exceptions can have a similar chain. The practical stuff:
- If you use MathLive, check your version with
npm ls mathlive, upgrade to 0.111.2 or newer, and declaremathVirtualKeyboard.originValidator = 'same-origin'(or a function with your allowed origins) instead of trusting the default. - Hunt down your own listeners:
grep -rnE "addEventListener\(.message|onmessage" src/. Each one must checkevent.originand alsoevent.source. MDN puts it bluntly: not checking them "enables cross-site scripting attacks". - Never accept HTML as configuration between windows. Send names from a fixed list.
- Dynamically created iframes, with
sandbox, especially if their content can come from another frame. - Audit your CSP exceptions. A big allowed domain in
script-srcmay have a JSONP endpoint that turns your policy into decoration. Parameter sums it up well: CSP is a backup defense, not the only barrier.
