OpenAI Account Takeover via libheif Heap Overflow and SSO Flaw: How Hacktron Chained a Malicious HEIF Image to Internal Repo Access — Analysis & Lessons

OpenAI Account Takeover via libheif Heap Overflow and SSO Flaw: How Hacktron Chained a Malicious HEIF Image to Internal Repo Access — Analysis & Lessons
Analysis by Faizan Akhtar.
A single photo upload was the entire entry point into one of the most closely watched companies on the planet. In July 2026, three researchers from Hacktron AI turned a crafted HEIF image into remote code execution on OpenAI's community forum, then crossed a far more consequential boundary: an identity flaw in OpenAI's single sign-on let them take over the ChatGPT and Codex accounts of anyone who had merely signed into that forum, including employees. One employee's GitHub-connected Codex then opened a pull request inside OpenAI's private internal monorepo — proof of access delivered, no code read, testing stopped. This is my original analysis of their publicly disclosed research: how the two bugs were found, why the chain worked, and what hunters and defenders should take from it.
Background
Harsh Jaiswal, Mohan Pedhapati and Rahul Maini — working as Hacktron AI — set out to probe the security posture of frontier AI companies and settled on OpenAI's community forum at community.openai.com, which runs on Discourse and offers "Sign in with OpenAI". What they found was not one vulnerability but two defects with a bridge between them: a memory-corruption flaw in the forum's image pipeline, and an SSO weakness that treated the forum's front door as a hallway into employees' accounts.
The timeline reads like a sprint. On July 23 they traced the forum's HEIF upload path to the vulnerable decoder; on July 24 they had a working exploit with ASLR disabled; on the morning of July 25 they had reliable code execution against the live forum, and that afternoon they opened the proof-of-access pull request and stopped testing — discovery to internal-repo access in under 72 hours. They reported the SSO-side finding through OpenAI's Bugcrowd program; OpenAI fixed it roughly 14 hours after submission and paid $6,500 for the OpenAI-side finding only (the forum itself was outside the bounty scope). The forum-side issue went to Discourse's HackerOne program: received on a Saturday, answered on a Sunday, fixed on Monday. The writeup was published in mid-September 2026, alongside a wider campaign tracing the same decoder weakness across other platforms.
The Vulnerability
1. A heap buffer overflow in libheif, reachable through the forum's image pipeline. Discourse checks uploads with FastImage, but FastImage could not parse HEIF files, so those uploads were diverted to ImageMagick's magick command — which delegates HEIF decoding to the libheif library. That delegation exposed the raw libheif parser to attacker-controlled files, and the decoder contained a heap buffer overflow yielding out-of-bounds read and write primitives. The supply-chain detail makes this case-study material: the faulty code had already been corrected upstream, but the commit was never flagged as a security fix and got no CVE. Treated as ordinary maintenance, it was never backported — the Discourse Docker image (Debian 12) shipped libheif 1.19.7 still vulnerable, and Debian 13 shipped 1.19.8 vulnerable too. A fix invisible to the people who decide what to backport is, from the attacker's perspective, no fix at all.
2. An OpenAI SSO identity flaw that crossed the trust boundary. The forum used "Sign in with OpenAI" through auth.openai.com. The second bug lived in how OpenAI's identity layer scoped that sign-in: with code execution on the forum, the researchers could take over the ChatGPT and Codex accounts of anyone signed in through that SSO flow — employees included — with no interaction from the victims. Because ChatGPT and Codex connect to services like GitHub, Slack and email, the blast radius extended into everything those connections could touch. The escalation is not Discourse-specific: any compromised service sharing that SSO arrangement would have offered the same path; the forum was merely the proof.
How It Was Found
This is a dependency-auditing find elevated by methodical pipeline tracing, and the discovery order matters.
The team started with an unglamorous question: where does this application hand files it cannot understand to someone else's parser? Following Discourse's upload handling, they spotted the FastImage-to-ImageMagick detour for HEIF — a format-exception branch reviewers skim past because it exists for compatibility, not security. They then asked an AI model to inspect the installed libheif package inside the Discourse Docker image, and it reported that certain fixes had never been backported. The model did not invent a zero-day; it found a genuinely unpatched, publicly committed bug and recognized its security significance. The flaw was "known" to upstream and invisible to downstream — the model's job was noticing the gap.
Opus 4.8 then built an exploit that worked only with ASLR disabled; hours after Anthropic released Opus 5, the newer model produced a working exploit that the team ported to the forum's x86-64 and jemalloc configuration. By 06:00 UTC on July 25 they had confirmed local RCE through an image upload. They tested against their own Discourse Cloud instance first — framed as a CTF target, since the model refused to aim at a remote production system — and only then ran it against community.openai.com at around 10:00 UTC. The final act: an employee's Codex, connected to OpenAI's GitHub organization, was instructed to open a single harmless pull request — #1186742 — in the internal monorepo. No source code was read or downloaded. Then testing ended.
That restraint is the model for the strongest impact demonstration that touches no sensitive data: a single, obviously harmless artifact created inside the target's own system of record — a claim about access converted into evidence of access.
Why It Worked
Every layer trusted the layer above it in a slightly different way, and nobody owned the boundary between them. The image pipeline trusted format detection: a file calling itself a photo was fed to a native decoder running with the application's privileges. The distribution trusted the upstream commit message: a fix without a CVE number looked like routine maintenance, so the backport never happened and the vulnerable library shipped for months. And the identity layer trusted the forum's front door: the SSO implementation failed to constrain a forum sign-in to forum-level access, so forum compromise became identity-wide compromise. That is the identity access management failure at the heart of the story — access was scoped to "this person proved who they are", not to "this person proved who they are, on this low-trust property, for this purpose".
The uncomfortable part: nothing here required a zero-day. The memory corruption was publicly committed upstream; the SSO issue was a configuration decision. What was new was the combination and the speed. The team's epilogue says it plainly: security has long relied on the quiet protection of complexity — bugs might be public, but weaponizing them demanded rare skill and time. When models compress months of exploit development into hours, that protection thins, and threat models must price in an adversary who can afford to try everything.
Lessons for Hunters
Map every parser your target delegates to. The find began where the application's own code ended: at the handoff to ImageMagick and then libheif. For every upload feature, trace the file past the application's checks and ask which native library eventually touches the bytes. Format-exception branches are where the interesting parsers hide.
Hunt unflagged upstream fixes. A security fix that never got a CVE is a backport that never happens. Diff upstream commits against the versions your target's distributions actually ship, and treat "fixed upstream, unflagged" as a live vulnerability class.
Treat shared SSO as shared trust — then attack the weakest party. Wherever a low-trust property shares single sign-on with high-value accounts, the property's security posture becomes the accounts' security posture.
Test inside the real artifact. The vulnerable component lived in the Docker image's Debian layer, not in Discourse's application code — a web-UI update would never have replaced it. Scope your target as the deployable unit (container image, not repo) and test what actually ships inside it.
Prove impact without touching the crown jewels. The pull-request proof is the model for responsible maximum-impact demonstration: an undeniable, reversible, in-system artifact requiring exactly the access claimed — nothing more.
Mitigation
- Rebuild self-hosted Discourse from the image, not the UI. Run
git pulland./launcher rebuild app— a web-interface update alone may not replace the vulnerable libheif inside the Docker image. - Update the native libraries and check backports. Install the latest security-patched libheif and libde265. Discourse's advisory GHSA-vhm9-85gw-x335 (July 28, 2026, CVSS 8.8) lists patched releases 2026.7.0, 2026.6.1, 2026.5.2 and 2026.1.6, and newer Discourse versions sandbox image processing as defense in depth.
- Isolate image processing. Decoder complexity guarantees future bugs in this family. Route untrusted images through hardened, ephemeral sandboxes, restrict accepted formats via ImageMagick's security policy, and disable HEIF/AVIF decoding where the business does not need it.
- Scope SSO sessions to the issuing property. A community-forum sign-in must not mint sessions usable against employee-grade accounts and their connected integrations. Audit every SSO relying party for this overreach, and shrink write scopes on connector grants attached to AI-agent accounts.
- Detect the probing, not just the payload. The campaign uploaded thousands of malformed images and was detected by only one company. Alert on decoder crashes and repeated malformed uploads to the same pipeline — that is the sound of someone building an exploit.
If you found this breakdown useful, read the earlier entries in this writeup-analysis series: my analysis of Pirikara's chained cross-account JavaScript execution in Basecamp's Fizzy — https://faizanakhtarcyber.blogspot.com/2026/10/basecamp-fizzy-cross-account-javascript-execution-analysis.html — and of 6r1ff1n's DuckDuckGo CI/CD RCE — https://faizanakhtarcyber.blogspot.com/2026/10/duckduckgo-pull-request-target-rce-writeup-analysis.html.
Report by Faizan Akhtar — The Cyber Security Researcher
Comments
Post a Comment