ChatGPT Account Takeover: One Shared Link Was Enough

ChatGPT Account Takeover: One Shared Link Was Enough

Agentic AI

Opening a public ChatGPT share link was enough. Parameter Labs found that a crafted shared conversation could run its own JavaScript as chatgpt.com in the visitor’s signed-in session, list their conversations, read a private one and send it to an outside server. OpenAI fixed it on October 26 and paid a $5,000 bounty. For anyone building AI apps that render generated HTML, the lesson is that the sandbox held, and the bug was everything around it.

What Happened

Simon Willison summarized the chain from Parameter Labs’ write-up. ChatGPT’s HTML Preview turns an HTML code block into a working page inside a restricted frame on a different web address, so it can’t read the ChatGPT page around it. That part worked.

The same conversation contained an ordinary interactive graph, which loads the MathLive math library. MathLive installs a listener in the main ChatGPT page for messages about its on-screen keyboard. The listener accepted a message from any origin that replaced the keyboard layout, and the layout could contain HTML, which MathLive assigned to innerHTML in the real page. A helper called createHTML looked like a sanitizer but passed the string through unchanged.

innerHTML doesn’t run script tags, so the researchers inserted an iframe using srcdoc. Because the main page created it with no sandbox attribute, it got the chatgpt.com identity. ChatGPT’s Content Security Policy blocked inline scripts but allowed YouTube, and a YouTube oEmbed endpoint reflected a callback parameter as JavaScript before returning a validation error. That gave full script execution.

The final step was delivery. Putting a genuine graph and a later HTML Preview in one public conversation preserved the whole chain in a /share link. In the automatic version, opening the link was the victim’s only click. The payload then called ChatGPT’s authenticated conversation APIs directly and exfiltrated data through an image request. Parameter Labs says it could perform any action on behalf of the account.

Why It Matters

OpenAI classified the report P1. Willison thinks the $5,000 payout was “a bit cheap for a vulnerability this serious.”

Parameter Labs is clear that every feature looked reasonable on its own. Preview was isolated, graphs could load a math keyboard, frames could exchange messages, CSP allowed a major media provider, and conversations could be shared. The exploit only existed when they met in one page.

What This Means for Builders

Artifacts and previews are now standard in AI products. Stack Archive covered Claude Code’s artifacts as live pages, and every such feature puts model-written HTML next to a signed-in session. Parameter Labs’ defensive list applies to all of them:

  • A message receiver should verify both the sender’s origin and the exact window it trusted.
  • Cross-window settings should never carry raw HTML.
  • Documents created from content an untrusted frame can influence should stay sandboxed.
  • CSP is a backup, not the only barrier. Blocking the YouTube endpoint alone would have left the HTML injection open.

The So What

Teams shipping AI features that render generated HTML should audit every postMessage listener in their main page, including those added by third-party libraries like charting and math widgets, and confirm each checks origin and window. Then test the shared or exported view of a conversation separately, since that is the version an attacker sends to someone else.

Source: Simon Willison's Weblog

Content created with AI assistance and reviewed for accuracy.

💬

Join the conversation

Stack Insiders is our free community for readers who want to go deeper — share resources, ask questions, and connect with others across every vertical we cover.

Join Stack Insiders →

Newsletter coming soon.

Curated digests across AI, biohacking, photography, travel, and more. Be the first to know when we launch.