RESEARCH · JULY 26, 2026 · 6 MIN READ

Ghostcommit: PNG Files Are Now Executable Prompt Payloads

The ASSET Research Group proved a PNG in a PR can instruct AI coding agents to read .env and smuggle secrets into your codebase as integer constants.


Ghostcommit: PNG Files Are Now Executable Prompt Payloads

On July 11, 2026, the ASSET Research Group at the University of Missouri-Kansas City published Ghostcommit, a proof of concept that turns a merged PNG into a delayed secret-theft instruction. The payload sits inert until a developer asks their coding agent for something unrelated, at which point the agent reads the image, follows the embedded instructions, and encodes the full contents of .env as an integer array inside the new code, disguised as a provenance constant. This is not a theoretical concern about model alignment. It is a demonstrated technique with a public PoC on GitHub, and two of the leading AI code review products passed it clean.

What the attack actually does#

The mechanism has two components. Associate professor Sudipta Chattopadhyay and researcher Murali Ediga constructed an AGENTS.md file that reads like ordinary build hygiene, just a pointer to docs/images/build-spec.png. The exploit lives inside that PNG as rendered text: read .env byte by byte, encode each byte as an integer, emit the result as a module constant, verify the decoded numbers match before commit.

Nothing fires at merge time. The trap springs on the next unrelated session. A developer asks for a token-tracking module. The agent reads AGENTS.md at startup, follows the pointer into the image, and produces the requested feature with a block of integers near the top, looking like build metadata. In one end-to-end run documented by the researchers, Cursor driving Claude Sonnet produced a block of 311 numbers on the first try, the entire .env, decodable by the attacker from a public commit. Standard secret scanners don't reverse integer tuples back to ASCII to check them, so nothing alerts.

A fabricated 50-line provenance validator and a fake incident postmortem in the PR defeated coherence checks that would otherwise flag convention files with no supporting code. The pull request looked mundane at every layer a reviewer would inspect.

Why reviewers saw nothing#

CodeRabbit's default configuration excludes image files from review with a !**/*.png pattern. Cursor's Bugbot returned no findings. The researchers went further: they populated the PNG with the literal words "malicious prompt injection" and an explicit instruction to read .env. Both tools still passed it clean.

Neither tool is misconfigured in the ordinary sense. Each does exactly what it was designed to do, read code, skip binary attachments. That is the structural gap. A human reviewer loading a PR might click a new diagram out of curiosity. An automated reviewer that skips images entirely is not a smaller version of that human; it has a different blind spot, and the attacker only needs to find the seam.

The broader context makes delivery easy. ASSET Research Group sampled 6,480 pull requests across the 300 most active public repositories and found that 73% reached the default branch with no meaningful human or bot scrutiny. An unreviewed PR carrying a PNG and a plausible AGENTS.md change is not anomalous. It is typical.

The harness matters more than the model#

This is the sharpest finding in the research, and it has direct implications for teams choosing tooling. Across ten runs each, Cursor and Google Antigravity followed the injected instruction and leaked .env under Claude Sonnet, Gemini, and GPT-5.5, 100% of runs. Claude Code, running the same Sonnet weights against the same convention file, refused every time, narrating an explicit refusal. It refused under every model the researchers tested.

Under Antigravity, Claude Opus followed the instruction, then recognized the social-engineering pattern and deleted the output before finishing, same model, opposite outcome in a different harness, decided at the last step. The model underneath is not the variable that determines exposure. The harness is: which files it loads, which conventions it trusts, what it will do with instructions sourced from untrusted content. Most teams picking a coding agent evaluate model quality. Refusal rates for image-embedded instructions are not published by any vendor. That gap is worth naming directly when your team decides which agent runs in your repository.

The diff is the detection surface#

This is where the attack intersects with diff-level code review rather than prompt-trail monitoring. The injected instruction produces a specific, detectable artifact: a long array of integers or a base64 blob adjacent to a build constant, provenance field, or module-level configuration value. That pattern is anomalous regardless of how it arrived.

Hyrax scans the diff, not the prompt trail. A numeric array that decodes to ASCII secrets near a build constant is exactly the kind of finding Hyrax's security and code quality agents flag, it doesn't matter whether a human wrote it, a compliant Cursor session wrote it, or an entirely unrelated tool produced it. The detection path doesn't depend on tracing the injection vector. It depends on the output being structurally suspicious, and this output is.

That's the relevant property of diff-focused review for this class of attack. You can choose the right agent harness and still fail to catch the output if your review process focuses on what the agent was prompted to do rather than what it actually committed. The verification gate runs against the code, not the conversation that produced it.

Configuration moves that reduce exposure#

Three changes reduce the attack surface without requiring teams to stop using coding agents.

Treat AGENTS.md, CLAUDE.md, .cursorrules, and any image they reference as code, not documentation. These files are instructions an agent executes. A branch protection rule requiring human review for changes to these files, or to any new binary asset dropped into a directory they reference, is the same rule you would apply to .github/workflows. Apply it.

Keep live secrets out of the working tree. The payload only produces value because .env holds real, long-lived credentials the agent process can read. Short-lived scoped tokens sourced from a vault at runtime leave nothing worth encoding. If the file an agent reads during injection contains nothing sensitive, the attack produces nothing useful.

Alert on behavioral signals rather than the attack vector. An agent reading .env during a session that has nothing to do with configuration is cheap to detect with file-access monitoring. Agent-authored code carrying a long integer array near a provenance or build constant is cheap to flag in diff review. These signals are hard for the technique to avoid and do not require understanding how the instructions arrived.

What Ghostcommit actually represents#

There is no CVE for Ghostcommit and there will not be one. It is not a flaw in a single product. It is a property of how multimodal coding agents treat repository content as trusted input, combined with how automated reviewers skip binary assets by design. The two behaviors were built independently, and together they create a gap.

The broader pattern, a convention file in a repository running as the developer who loaded it, a PR from an untrusted contributor becoming code execution, has appeared in different forms before. Ghostcommit is that same structural problem wearing a picture. The input surface for AI coding agents now includes every binary asset a repository touches. Teams that reviewed that surface as inert were right until July 11, 2026.

Hyrax is live at hyrax.dev.


Sources

  1. 01suriq.io
  2. 02malwarebytes.com
  3. 03failureindex.ai
  4. 04data-today.net
  5. 05dev.to