Back to Blog
Incident Analysis
By 
Raven Research
September 18, 2026

The OpenAI Breach Started with an Exploit in an Open-Source Library

A forum image upload should end with a picture—not access to an internal code repository.

Yet that is the chain Hacktron researchers demonstrated. A crafted HEIF image enabled remote code execution in OpenAI’s Discourse-hosted community forum. A separate OpenAI single sign-on flaw then enabled access to ChatGPT and Codex accounts. Using an employee’s connected Codex account, the researchers opened a harmless pull request in an internal repository to prove their access. They reported the findings; according to their disclosure, OpenAI confirmed its fix on July 25, 2026. (hacktron.ai)

View image

The starting point was not an AI model. It was an image-processing library several layers below the application.

That makes this more than a story about one company’s security incident. It raises a question every organization running third-party code should ask:

What is a dependency allowed to do after something goes wrong inside it?

First, what is a HEIF file?

HEIF stands for High Efficiency Image File Format. It is a format for storing images efficiently, familiar to many people through photos captured on Apple devices. Apple adopted HEIF to preserve visual quality while using less storage than JPEG. (support.apple.com)

The familiar .heic extension generally refers to HEIF images compressed using HEVC, also known as H.265. But HEIF is more than a compressed picture: it is a container that can hold multiple images, thumbnails, transparency information, depth maps, and instructions for arranging or transforming image content. The open-source library libheif handles these structures and coordinates decoding. (github.com)

An overlay, for example, tells the decoder how to combine one image with another. Processing it involves interpreting dimensions, positions, transparency, and memory layouts.

None of this makes an ordinary HEIF photograph malicious. It does mean that displaying or converting one requires software to interpret a complex structure supplied by the uploader.

“Accept an image” is also “run a parser on someone else’s data.”

The attack surface was below the application

Image-processing dependencies often enter production indirectly: through a framework, an image-conversion tool, an operating-system package, or a container image. Hacktron’s broader HEIF research identifies native decoders such as libheif behind higher-level tools including ImageMagick and libvips. (heif-heist.com)

In the disclosed forum case, the initial path was:

HEIF upload → Discourse → ImageMagick → libheif → remote code execution. (hacktron.ai)

The important distinction is between the feature the application offered and the code that actually processed the input.

The feature was image upload. The security-sensitive work happened inside a native decoder.

The upstream change referenced in the disclosure concerned image overlays. It revised calculations used to determine where two images overlap and how their boundaries should be handled. These calculations govern which parts of image buffers the decoder accesses. (github.com)

When a decoder mishandles those boundaries, the consequences can extend beyond a broken image. Debian’s subsequent libheif advisory described vulnerabilities that could expose memory, crash applications, or potentially enable arbitrary code execution when malformed images were processed. Discourse separately confirmed remote code execution through malformed HEIF uploads. (lists.debian.org; Discourse advisory)

The file did not need to be a program in the normal sense. It needed to make the program processing it behave incorrectly.

A vulnerable dependency can become an entry point. Runtime security needs to control what happens next.

A fix in a repository is not a fix in production

According to Hacktron, relevant code had already changed upstream, but the change was not identified as a security fix. The downstream package used by Discourse still contained the vulnerable implementation. (hacktron.ai)

This exposes an important gap between three different events: a maintainer changing code, a downstream distributor shipping the fix, and an organization actually running the corrected package.

Discourse’s advisory addressed the deployment layer directly. Its updated Docker image included patched libheif, and the remediation required rebuilding the application image. Updating application code alone is not the same as replacing a vulnerable dependency in the underlying environment. (github.com)

Debian’s update also illustrates why version numbers need context: it delivered security fixes in a distribution package carrying an older upstream version number. The relevant question is not simply whether the version looks old, but whether the deployed package contains the necessary fixes. (lists.debian.org)

The lesson is not that patching fails or that vulnerability management is unnecessary.

It is that runtime protection should not depend on every upstream fix being recognized, packaged, prioritized, and deployed before someone exploits the gap.

AI helped turn the gap into an attack

Hacktron reports that Claude models helped develop the exploit, with a newer model succeeding where earlier attempts had struggled. Skilled researchers still guided the work. (hacktron.ai)

That distinction matters. This was not an AI system magically bypassing every security boundary. It was AI assisting researchers with the difficult work of turning a software defect into a usable attack.

For defenders, the implication is straightforward: the effort required to exploit a bug is not a dependable security control.

A protection model should remain useful even when developing the next exploit becomes faster.

An image decoder needs to execute code. It does not need unlimited authority.

Every decoder executes code—that is how it turns compressed data into pixels.

But executing its own decoding instructions is not the same as launching arbitrary operating-system programs.

Consider a local image-conversion workflow. Its intended job might require reading an uploaded file, allocating memory, using approved codecs, and writing the converted result. That does not automatically justify access to unrelated application secrets, arbitrary outbound connections, or unrestricted process creation.

This is not an argument for blindly prohibiting every helper process. ImageMagick can legitimately use external programs, and its security policy supports controlling those delegates, accepted formats, file paths, and resource usage. Restrictions have to match the actual workflow. (imagemagick.org)

The useful security question is therefore more precise than “Can this application start a process?”

It is:

Which component is initiating the action, through which execution path, and does that component need that capability here?

A permitted image-conversion helper and an unexpected executable launched through a compromised decoding path should not be treated as equivalent simply because both originate from an approved application.

Raven’s approach: control the action, not just classify the dependency

Raven’s runtime approach focuses on the library and execution path behind sensitive activity. Instead of reducing an event to “the application opened a connection” or “the application started a process,” it adds the context needed to identify the component that originated the behavior. (raven.io)

That enables a more specific enforcement model.

The application can retain capabilities it legitimately needs, while a particular component is prevented from exercising a capability through a prohibited path. For supported workloads and operations, prevention can target the sensitive action rather than require a signature for the exact payload or advance knowledge of the vulnerability. (raven.io)

Applied as a policy principle to image processing, the goal is straightforward:

Allow the intended conversion. Prevent unrelated capabilities from becoming available through that conversion path.

This is different from trying to recognize every malicious image. The policy does not need to understand every possible variation of an attacker’s file. It needs to identify and enforce the boundary around the action the component is attempting.

It is also different from making memory corruption impossible. Preventing process creation does not, by itself, prevent every in-memory attack or information leak. The protection applies when an attack reaches an operation covered by reliable attribution and an active enforcement policy.

For the specific libheif/ImageMagick chain, claiming successful Raven prevention would require validating those conditions in the affected workload. This analysis explains the enforcement model; it does not claim a reproduction or prevention result for the OpenAI incident.

Patch the flaw. Restrict what a compromised component can do.

Discourse’s response is instructive. Alongside the patched dependency, it added sandboxing for image processing. Its implementation restricts filesystem access and network use, rather than simply giving the image-processing command the full rights of the calling process. (github.com)

That is a useful architectural lesson: fix the known vulnerability, but also reduce the authority available to the next one.

Image-processing isolation, dependency updates, identity boundaries, and library-aware runtime enforcement address different parts of the problem. They are complementary—not interchangeable.

The question is not whether every dependency can be made permanently safe.

It is whether a dependency’s failure must become permission to do something entirely outside its purpose.

An image decoder needs to decode images. It should not inherit permission to do everything else.

See how Raven brings library-level visibility and prevention to application runtime.

Share this post