· via Hacker News – Front Page (hnrss.org)
Public ChatGPT share links allowed account takeover via sandbox escape, now patched
Security researchers showed that a single public ChatGPT share link could execute attacker JavaScript inside a signed-in session and read private chats; OpenAI patched the flaw and rated it P1.

What happened
In October 2026, security researchers at Parameter worked out how to convert an ordinary public ChatGPT share into attacker-controlled JavaScript running inside the signed-in session of whoever opened it. According to the team's write-up, which reached the front page of Hacker News, an attacker could craft a conversation, publish it through ChatGPT's normal sharing feature, and send the link to a victim. Opening the link was the only step required of the victim: no app installation, no project membership, no pasted code, no developer tools.
Parameter says the executed payload could list the victim's conversations, pull the contents of private chats the attacker had never been given access to, exfiltrate that data to an outside server, and invoke ChatGPT's authenticated APIs in the victim's name — effectively a full account takeover. OpenAI fixed the issue on October 26 and classified the report as P1.
A graph and a preview created the gap
ChatGPT's Preview feature turns an HTML code block into a small working page. Because such a page can contain arbitrary code, ChatGPT runs it inside a restricted frame hosted on a different web address, so the browser treats it as a separate site and blocks it from reading the signed-in page around it. Parameter says that boundary initially held: the Preview could not read the main document.
Interactive graphs, however, load a math library called MathLive. Loading it also installs a listener in the main chatgpt.com page that handles messages tied to MathLive's on-screen virtual keyboard, using the browser's postMessage API. That channel works across origins, but it is safe only when the receiver verifies who sent each message.
MathLive skipped that verification for the setting Parameter targeted. Its top-level controller accepted messages from any origin, and it did not require the layout-update message to arrive from a window it had previously approved. One accepted message type swapped the virtual keyboard layout — and layouts were permitted to contain HTML.
Injecting HTML into the main page
The sandboxed Preview sent two messages: one replaced the keyboard layout with the researchers' HTML, the second told MathLive to display the keyboard. When the keyboard rendered, MathLive assembled the layout into an HTML string and wrote it into the real ChatGPT page via innerHTML. A helper called createHTML gave the appearance of sanitization but simply flagged the string as trusted and let it through.
Script tags inserted this way do not execute, so Parameter embedded an iframe using srcdoc. MathLive inserted that frame into the main ChatGPT document with no sandbox attribute. Two consequences followed: srcdoc provided a fresh document where a script could run, and because the main page had created the frame, the browser assigned it chatgpt.com's identity, allowing its contents to reach the parent page.
Bypassing the content security policy
ChatGPT's Content Security Policy blocked inline JavaScript but still allowed scripts sourced from YouTube. YouTube's oEmbed endpoint supported a JSONP-style callback parameter and, although it rejected invalid callback names, it included the callback in the body of the error it returned. By ending the callback with ";void", Parameter neutralized the trailing object YouTube appended, so the browser executed the error response as a script from an allowed origin inside the new frame. With that, arbitrary JavaScript was running as chatgpt.com while the original Preview stayed confined to its separate address.
From lab bug to a single link
The first working version was not yet a practical attack, because it relied on the victim connecting a researcher-controlled ChatGPT App. An HTML attachment opened in the sandboxed Preview could carry the payload, but exporting a conversation as a public share dropped the graph — the component that loaded MathLive and installed the vulnerable listener in the first place.
The breakthrough was combining both halves in one ordinary public conversation: a genuine graph to initialize MathLive, followed by an assistant-authored HTML Preview to fire the two messages. The resulting share URL preserved the entire chain and could be distributed like any shared conversation. In the most stable reproduction the victim clicked ChatGPT's normal Preview button once; after the researchers flagged the HTML block as previewable, opening the link was the only click.
Why it matters
This is a textbook composition failure. The Preview sandbox, the postMessage listener, the trusted-HTML helper, the CSP allowlist and YouTube's JSONP endpoint each looked defensible in isolation; stacked together they yielded a one-click takeover. Builders of frame-based sandboxes can take away concrete checks: validate postMessage origins, make trusted-type wrappers genuinely sanitize, and sandbox srcdoc frames.
Delivery mattered as much as the exploit. A share link is a native ChatGPT artifact that users have no reason to distrust, so the usual warning signs of an attack were absent. OpenAI's P1 rating and rapid patch reflect that severity; the write-up does not address whether the flaw was abused before the fix, but any signed-in user who opened an unfamiliar shared conversation was in scope.
- #security
- #openai
- #chatgpt
- #vulnerability
- #xss