Anatomy of a ChatGPT Account Takeover: One Link, One Click, Full Session
By Arash Latifi
How Parameter chained a MathLive postMessage flaw, unsanitized innerHTML, and YouTube JSONP to bypass ChatGPT's sandbox and CSP — and what your app should learn from it.
TL;DR — Parameter's researchers chained three weaknesses (an origin-blind MathLive listener, unsanitized innerHTML, and YouTube's JSONP endpoint) to run attacker JavaScript inside a victim's signed-in chatgpt.com session via an ordinary share link; OpenAI fixed it on October 26 as P1.
The attack: just one click
In October 2026, Parameter found they could publish a malicious conversation through ChatGPT's normal Share feature and send the link to a victim. The only required action was opening it — no app install, no pasting code, no dev tools. The payload then ran as chatgpt.com inside the victim's authenticated session, and could enumerate conversations, read private chats never shared with the attacker, and exfiltrate them to an external server. OpenAI fixed the issue on October 26 and classified it P1.
The chain: three flaws, none sufficient alone
ChatGPT runs HTML Preview code in a restricted frame on a separate origin; it couldn't touch parent.document. Three flaws tore the wall down:
| Step | Flaw | Result |
|---|---|---|
| 1 | MathLive's postMessage listener: no origin check, no approved-sender requirement | Preview messages injected into the main page |
| 2 | Keyboard layout HTML assigned to innerHTML unsanitized | DOM injection into the main document |
| 3 | CSP allowed YouTube; YouTube's oEmbed endpoint executed JSONP callbacks | CSP bypass, arbitrary script execution |
Step 1: the mail slot with no guard
An interactive graph in the conversation loaded the MathLive library into the main page, which registered a postMessage listener for its virtual keyboard. That listener accepted a layout-update message from any origin, and layouts could contain HTML. The restricted Preview became an untrusted sender with access to the slot:
Step 2: innerHTML is not a sanitizer
When the keyboard opened, MathLive joined the supplied layout into an HTML string and assigned it to innerHTML on the real page. A helper named createHTML looked like it might sanitize — it didn't; it marked the string as trusted and passed it through unchanged. Plain <script> tags inserted via innerHTML don't execute, so the attacker used an iframe with srcdoc: because the main page created the frame, the browser gave it the https://chatgpt.com identity and access to its parent.
Step 3: bypassing CSP with YouTube JSONP
ChatGPT's CSP correctly blocked inline scripts but allowed youtube.com. YouTube's oEmbed endpoint placed its callback parameter into the response before returning a validation error — so the response body executed attacker-chosen JavaScript:
https://www.youtube.com/oembed?callback=globalThis.__marker=31337;void
That was the last link in the chain.
Related: CVE-2026-98432: Your Linux Server May Be Vulnerable Right Now — check your servers today.
Lessons for your own app
Any application with iframes, postMessage, or third-party scripts owns these lessons:
- Every
postMessagelistener must check the sender's origin. "The format looked right" is not authentication — any page in any tab can post a message. innerHTMLalone never sanitizes. If you use Trusted Types–style APIs, verify the policy actually filters rather than just marking strings trusted.- A CSP allowlist is as strong as its weakest allowed domain. YouTube, fonts, CDNs — each can become an escape hatch (JSONP, redirects).
- Evaluate features together, not in isolation. Graph + Preview + Share were each fine; the combination was P1.
Quick audit checklist
- [ ] Every
addEventListener("message", ...)validatesevent.origin - [ ] No user-controlled input reaches
innerHTMLwithout real sanitization - [ ] Embedded iframes carry a
sandboxattribute - [ ] Reviewed CSP: is every allowed domain actually necessary?
- [ ] Checked third-party endpoints (oEmbed, JSONP, widgets) for code execution
- [ ] Tested your share/link-preview flow as an attacker would
FAQ
Q: Is this bug still dangerous?
A: No — OpenAI fixed it on October 26, 2026 and rated the report P1. The value now is the architectural lessons, not an active threat.
Q: My app isn't ChatGPT — is this relevant?
A: Yes. The pattern (postMessage without origin checks + innerHTML + a CSP allowlist with a third-party domain) reproduces in any web app with iframes or third-party widgets. The specifics come from Parameter's writeup; the injection point is the one you have to find in your own code.
Q: Are ChatGPT share links safe now?
A: Per Parameter, the fix shipped October 26 and "just opening the link" no longer leads to takeover. The general principle stands: every link you open executes with your session, and every share sends content to an external page.