
A ChatGPT shared link bug found by Parameter let a crafted conversation run attacker code inside a victim's signed-in chatgpt.com session and read a private chat never shared with anyone else. OpenAI fixed it in eight days, but the chain shows how the rendering layer around an LLM becomes a direct path into the account.
Key takeaways
- Parameter showed a crafted ChatGPT share link could run code in a signed-in session after one Preview click, and in a later variant with no click beyond opening the link.
- The Preview sandbox held; a MathLive keyboard listener in the main page accepted HTML from any sender, and a YouTube-hosted script allowed by CSP finished the chain.
- The proof called ChatGPT's authenticated APIs, listed recent chats, and read a private chat never shared with the attacker.
- Reported October 18, 2026, fixed by OpenAI by October 26, rated P1 after an initial P2, and paid $5,000 in total. No CVE, no known exploitation.
- This is a web client trust-boundary bug, not prompt injection: AI front ends, share links and RAG rendering need XSS-grade testing.
What did the ChatGPT shared link bug actually do?
A crafted ChatGPT shared-conversation link could run attacker-supplied code inside a victim’s logged-in chatgpt.com session, list their recent chats, and open one they had never shared. Security firm Parameter found the chain and reported it through OpenAI’s bug bounty program on October 18, 2026.
OpenAI rolled a fix across two versions of the ChatGPT web frontend, and by October 26 both rejected the messages the attack depended on. Parameter published its writeup on October 28, and The Hacker News covered it on October 31.
The victim workflow should bother anyone who runs a support desk or a busy Slack workspace. There was nothing to install, no workspace to join, and no attacker-run sign-in page. In the variant Parameter calls most reliable, the victim opens the shared link and clicks ChatGPT’s Preview button once.
A later variant opened Preview automatically, so loading the link was the entire interaction. Delivery looks exactly like a normal shared chat: email, a chat message, a support ticket, a social post. People paste ChatGPT share links into tickets and team channels every day, and the URL sits on chatgpt.com, a domain most mail filters and most people already trust.
Before going further, pin down the scope:
- Parameter ran a controlled test between separate accounts and reports no real-world exploitation.
- There is no CVE and no CVSS score. The P1 and P2 labels in the reporting are OpenAI’s internal bug bounty priorities.
- The fix is on OpenAI’s side. ChatGPT users have nothing to install, reset, or change.
Why didn't the Preview sandbox stop it?
Because the sandbox was never the weak point. The untrusted message was accepted by MathLive, a math-input library that ChatGPT loaded into the main chatgpt.com page. That distinction is the crux of the story.
Preview renders HTML from a conversation as a small web page inside a locked-down frame on a separate web address, where it cannot read the ChatGPT page around it. That sandbox held, and Parameter did not break out of it directly. What a sandboxed frame can still do is send postMessage events to other windows, including its parent.
The browser delivers those messages without checking anything. Whether a message does harm depends entirely on the code that receives it.
The receiver came from a second feature in the same shared conversation: an interactive graph. Rendering it pulled MathLive into the top-level page, and MathLive left a listener running for messages about its on-screen keyboard. That listener had two properties that were dangerous in combination:
- It accepted keyboard configuration messages from any sender, with no check on which window had posted them.
- The message could carry raw HTML as keyboard-layout data.
So the Preview frame, still inside its sandbox, posted a keyboard-settings message upward, and the main page’s MathLive handler passed the attacker’s markup into the trusted document. No browser bug was involved. The browser did what the page told it to do.
Standard postMessage practice is for the receiver to verify the sender’s origin and source window before acting. Restricting the target origin on the sending side protects the sender, not the receiver. Here the attacker controlled the sender, so only a receiver-side check could have stopped the chain, and there was none.
How did an unsandboxed frame inherit chatgpt.com?
The injected HTML built a new frame from inside the main page, and the browser treated that frame as part of chatgpt.com, with no sandbox restrictions. That jump in privilege is the heart of the exploit. Markup that started in an isolated Preview now had a child frame running as the real site.
ChatGPT’s content security policy should have been the next wall, and it partly was. It blocked inline script, so the new frame could not carry the attacker’s code in its own markup. But the policy allowed scripts from YouTube, and a YouTube-hosted script supplied the code that ran in the new frame.
A CSP host allowlist answers one question: is a script from this location acceptable? Once an allowed script runs, it runs with the embedding page’s origin and privileges. YouTube did nothing wrong here. It was simply a permitted location that could be bent into delivering code.
Parameter is explicit that the YouTube step was the final workaround, not the cause. Block it alone and an untrusted Preview could still push HTML into the main site; an attacker would go looking for the next allowed host. The researchers trace the bug to three design choices that lined up:
- MathLive acted on a settings-changing message without checking which frame sent it.
- The message format allowed raw HTML as keyboard-layout data.
- That HTML could create an unsandboxed frame that inherited the chatgpt.com identity.
Fix any one of the three and the chain breaks. That is the useful lesson for code review. CSP is a mitigation layered on top, and a team that answers a client-side injection report by tightening CSP alone has patched only the last hop.
How far could code inside the session reach?
It could reach everything the victim’s ChatGPT web session could reach. The code called ChatGPT’s own signed-in APIs directly instead of scraping the screen, hitting the same backend the real frontend uses with the victim’s full web access. Its reach was the account, not the shared chat it arrived in.
Parameter’s proof did three things: it listed the victim’s recent conversations, opened a private chat never shared with the attacker account, and sent a small portion of that chat to a researcher-controlled server. The researchers’ own summary of the ceiling: “Essentially, we could perform any action on behalf of the victim’s ChatGPT account.”
No cookie theft was needed. HttpOnly cookies stop JavaScript from reading session tokens, but the browser attaches those cookies automatically to requests from same-origin script. The attacker never holds the credential. Every request leaves the victim’s own browser, IP address and user agent, so in server logs the attacker’s activity looks like the user clicking around.
Company ChatGPT histories hold pasted source code, contract drafts, incident notes, and customer data that should never have been pasted in. One link in a support ticket and one Preview click made all of it readable by whoever wrote the conversation. Parameter’s proof deliberately took a sliver; the realistic blast radius was the whole history.
Is this classic XSS or prompt injection?
It belongs to the DOM-based XSS family and has nothing to do with prompt injection. Attacker-controlled data written into the DOM through a message handler is textbook DOM XSS, so the bug class is not new. What differs from the XSS findings most teams triage is the delivery, the isolation model, and the value of the session.
- The vector is a product feature. Reflected XSS needs a crafted parameter on a target URL. Stored XSS needs a write into a page other users view. Here the share feature exists to publish user-authored content, including renderable HTML, to anyone with the link, and the link points at the vendor’s own domain.
- The sandbox was correct and still irrelevant. Most XSS writeups end at unsanitized output. In this chain the untrusted HTML was properly isolated. A third-party library in the parent page opened a side door the sandbox design never accounted for.
- The session is worth more. XSS in a CRM reads CRM records. XSS in an AI assistant reads everything every employee asked it, and increasingly the tools and data sources it is wired to.
The model was never manipulated, and no instruction was smuggled into its context. Guardrail testing, jailbreak suites and model red-teaming would not have caught this. We made a related point when Grok’s share pages were abused for SEO spam: share pages on AI products are public web content first and need to be tested that way.
For most teams that means DOM and stored XSS testing aimed at the AI front end, not just at the model behind it.
Did the P1 rating and $5,000 bounty match the impact?
The P1 rating matched; the $5,000 payout looks modest. OpenAI first rated the report P2, then raised it to P1, its most serious priority category, after reproducing both the code execution and the private-chat proof. That is normal triage: “HTML lands in the parent frame” reads like a medium finding until the vendor watches a private chat leave a second account.
The response speed deserves credit. Eight days from report to both frontend versions rejecting the attack messages is fast. Parameter held its writeup until after the fix and published two days later, which is how coordinated disclosure is supposed to work.
The money is a separate question. For $5,000 in total, OpenAI got a one-click path to account-level read access across every chat (and in the later variant, no click at all beyond opening the link), delivered through a URL on its own trusted domain.
Our view: that is priced like a component bug, not a session takeover. Bounty size is not a severity score, and OpenAI sets its own tables. But researchers price their time against those tables, and this chain stitched together two product features, a third-party listener, frame inheritance and a CSP allowlist bypass. Pay chains like single-component bugs and fewer get reported; the same effort sells for more elsewhere.
What is still unknown about the ChatGPT Preview vulnerability
OpenAI has not published version numbers for the two frontend builds, and there is no CVE, patch identifier or public commit to read. Other gaps matter for anyone doing a retrospective risk assessment:
- Exploitation before the fix. Parameter reports no real-world use, and nobody has said otherwise. No indicators or detection queries were published, so “no known exploitation” is not proof that none occurred.
- Exposure window. The reporting does not say when the MathLive integration or the auto-opening Preview shipped.
- Scope. Plan tiers, enterprise workspaces, mobile and desktop clients, and whether “any action” extended to connected apps or memory are not addressed. The research targets the web frontend.
- Other libraries. Whether OpenAI audited every other third-party component in the main page for the same listener pattern is not stated.
Enterprises with retained ChatGPT audit logs can review the period before October 26, but attacker requests came from victims’ own browsers and will be hard to separate from normal use.
What should an AI web-client test include after this?
Assume every piece of content the product renders from another user is attacker-controlled, then follow every channel that content can reach in the main origin. For ChatGPT that content was a shared conversation. For your internal assistant it may be a shared prompt, a saved workflow, or a document pulled in by retrieval. Scope should cover:
- Share and export features as delivery paths. A share link lands in a logged-in session looking like legitimate collaboration. Test what it renders, what renders automatically, and what one click triggers.
- Every message listener in the top-level origin, including those registered by third-party libraries for math, charts, diagrams and code editors. Each one is an authorization boundary and needs an exact origin allowlist plus a check on the expected source window before any parsing.
- Settings and layout messages that carry HTML. Configuration should be structured values. If HTML is unavoidable, sanitize it against an allowlist that excludes frames, srcdoc, objects and scripts.
- Frames created by the main page. Check sandbox attributes on anything built dynamically, not just on the frames in the original design.
- The CSP script-src allowlist as an exploit path. For each allowed host, ask whether an attacker can get it to serve script they influence.
- Authenticated API abuse as the proof. When script lands, demonstrate an API action: enumerate history, read a document, invoke a tool. A popup alert understates the finding and invites a P2, as happened here at first.
Internal assistants and RAG front ends carry the same risk plus one more source. If your assistant renders retrieved content as rich output (HTML, markdown with embedded markup, charts, previews), every document in the index is a potential share link.
A poisoned wiki page can do the job Parameter’s crafted conversation did, and the session often holds SSO access to the systems behind the index. That is why our RAG pipeline assessments follow retrieved content all the way to the browser, not just into the prompt.
Practitioner’s note
On internal AI assistant engagements, model-facing tests tend to get the budget and the rendering layer gets an afternoon. The pattern to hunt for is the one in this chain: a chart, diagram or math component that registers a window message listener with no origin check, often arriving as a transitive dependency after the original security review.
Search frontend source and bundled vendor code for message event listeners, then trace whether any reach HTML sinks such as innerHTML, insertAdjacentHTML, srcdoc or dynamic iframe creation. Confirm origin checks are exact string matches, not suffix or regex tests a lookalike domain can satisfy. Then pull your production CSP header and list every host in script-src. Our LLM application penetration testing treats the browser client as part of the AI attack surface for exactly this reason.
FAQ
Is the ChatGPT shared link bug still exploitable?
No. OpenAI rolled a fix across two versions of the ChatGPT web frontend, and by October 26, 2026 both rejected the messages the attack depended on.
Do I need to reset my ChatGPT password after the shared link flaw?
No user action is required. The fix is on OpenAI's side, and the attack worked through the victim's browser session rather than by stealing passwords or session tokens.
Was the ChatGPT Preview sandbox broken?
No. The Preview frame stayed sandboxed. The flaw was a MathLive message listener in the main ChatGPT page that accepted HTML from any sender, including the sandboxed Preview.
Did a shared ChatGPT link expose private chats?
In Parameter's controlled test between separate accounts, yes: the code listed recent conversations and opened a private chat never shared with the attacker. Parameter reports no real-world victims.
What did OpenAI pay for the ChatGPT share-link bug?
OpenAI paid Parameter $5,000 in total and rated the report P1, its most serious priority category, after initially rating it P2.
Is the ChatGPT shared link bug a prompt injection attack?
No. The model was never manipulated. It was a DOM-based script injection in the web client that ran code with the victim's chatgpt.com session.
If your company runs an internal assistant, a RAG front end, or a customer-facing LLM app, agent::offense tests the full stack, from model behavior to the browser client that renders its output. See our AI and LLM agent security testing.