Researchers demonstrated a full account takeover via a malicious public ChatGPT share link that executed arbitrary JavaScript in the victim's authenticated session. The exploit chain combined four features: the HTML Preview sandbox, an interactive graph loading the MathLive library, cross-frame postMessage communication, and a YouTube oEmbed JSONP endpoint allowed by CSP. MathLive installed a message listener in the main chatgpt.com page that accepted keyboard-layout updates containing raw HTML without validating event.origin or event.source. The attacker's Preview iframe sent two messages: one injecting an iframe with a srcdoc attribute containing a script tag pointing to YouTube's oEmbed endpoint with a malicious callback, and another triggering the keyboard render. MathLive assigned the HTML via innerHTML using a createHTML helper that did not sanitize, creating an unsandboxed iframe inheriting the chatgpt.com origin. CSP blocked inline scripts but allowed www.youtube.com; the JSONP endpoint reflected the callback before validation, and appending ;void neutralized the appended error object, achieving code execution. The payload then read #client-bootstrap from the parent, extracted the Bearer token and ChatGPT-Account-ID, and called authenticated backend APIs: GET /backend-api/conversations?limit=20 to enumerate conversations and GET /backend-api/conversations/ ?num_turns=2 to retrieve private message content from a never-shared conversation, exfiltrating data via an image request. OpenAI reproduced the issue, escalated severity to P1, deployed fixes across two frontend versions by October 26 blocking the cross-frame messages, and awarded a $5,000 bounty. The root cause was insufficient postMessage authentication, HTML injection into a privileged context, unsandboxed dynamic document creation, and reliance on CSP as a primary barrier.
Read original
hackernews