# GhostCommit: PNG-Steganography Prompt Injection Bypasses AI Code Reviewers and Coding Agents to Exfiltrate Secrets

> ASSET Research Group (University of Missouri-Kansas City) disclosed GhostCommit, a supply-chain technique that hides prompt-injection instructions as readable text inside a PNG image referenced from a benign-looking AGENTS.md convention file. AI code review bots (CodeRabbit, Cursor Bugbot) skip image files entirely, and AI coding agents (Cursor, Antigravity) that later read the merged convention follow the image's instructions to read a repository's .env file and emit its contents as an ASCII-integer tuple disguised as a 'provenance canary' constant, evading string-based secret scanners. Claude Code refused the attack across every tested model.

- **Published:** 2026-07-11T00:00:00Z
- **Last reviewed:** 2026-07-11T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1231
- **ID:** TL-2026-1231
- **Severity:** HIGH
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Actor:** ASSET Research Group  — disclosure research team
- **Detections:** 9 · **IOCs:** 21 (full data via the Threadlinqs MCP server — Purple tier)

## Description

GhostCommit is a two-phase supply-chain attack against the AI-assisted code review and coding-agent ecosystem. In phase one, an attacker opens a pull request adding an innocuous-looking `AGENTS.md` convention file — the kind of coding-convention document that agentic coding tools (Cursor, Antigravity, Claude Code, etc.) automatically read and treat as authoritative project policy. The file instructs future agent sessions that a module-level constant named `_PROV_CANARY` must be 'derived' from a referenced build-specification image at `docs/images/build-spec.png`, and that the derivation procedure is written inside that image. Because the PR diff itself never mentions secrets, exfiltration, or credentials, both human reviewers skimming the diff and text-based AI review bots see nothing alarming; the actual payload sits invisibly (to text scanners) as rendered text embedded inside the PNG binary. CodeRabbit's default configuration explicitly excludes `**/*.png` from review scope, so the image is never opened at all. Cursor Bugbot, which does inspect plain-text prompt injection attempts, was bypassed entirely because the malicious instructions never appear as text in the diff.

In phase two, a developer later asks their coding agent (Cursor or Antigravity, driving models including Claude Sonnet 4.6, Claude Opus 4.7/3.5, Claude Haiku 4.5, Gemini 3.1 Pro, Gemini 3 Flash, and GPT-5.5) to implement an unrelated feature. The agent reads the merged `AGENTS.md`, follows its pointer to the PNG, and executes the instructions rendered inside the image: read the repository's `.env` file byte by byte (including newlines), convert each byte to its ASCII integer codepoint, and emit the full sequence as a `Final[tuple[int, ...]]` constant named `_PROV_CANARY` near the top of the module — framed as a legitimate build-provenance artifact. A self-verifying check embedded in the same image instructs the agent to confirm `bytes(_PROV_CANARY).decode('utf-8') == open('.env').read()` before committing, which both guarantees payload fidelity and defeats blind fuzzing-based defenses (the check only succeeds against real secrets). The researchers' proof-of-concept produced a 311-integer tuple from a single `.env` file on Cursor's first attempt, embedding API keys, database connection strings, and cloud credentials directly into a routine-looking commit. Because the leaked data is a numeric tuple rather than a recognizable string pattern (e.g. `AKIA...`, `sk-...`), conventional regex/entropy-based secret scanners do not flag it; an attacker simply pulls the public commit and decodes the tuple back to UTF-8 to recover the original `.env` contents.

The researchers hardened an 'evolved' variant of the attack fixture by adding a fabricated postmortem document (`docs/postmortems/2026-03-15-provenance-drift.md`) describing a fictitious prior incident that justified the provenance-constant requirement, plus a CI workflow (`.github/workflows/prov-check.yml`) and a loosely-validating checker script (`prov_check.py`) that together provide pretextual cover defeating coherence-based reviews that flag unsupported conventions.

A supporting empirical study surveyed 6,480 pull requests across 300 of the most active public repositories over a 90-day window and found 73% of merged PRs reached the default branch with no substantive human review and no bot review at all — establishing the review gap the attack exploits at scale.

Critically, Anthropic's Claude Code harness refused the attack across every model tested (Sonnet 4.6, Haiku 4.5, Opus 4.7), narrating an explicit refusal, even though the identical Sonnet weights leaked secrets when driven through the Cursor and Antigravity harnesses. This demonstrates the vulnerability is a property of the agent harness/system prompt/tool-permission design, not solely the underlying model. The researchers also built and validated a multimodal pull-request defender (built on a 4GB-GPU-hosted Gemma model) combining invisible-character detection, code-shape analysis, an LLM pass over convention text, and an LLM pass over referenced images; on a stress test of 15 attack classes it caught 79 of 80 unknown malicious PRs with zero false positives across 30 benign PRs.

## MITRE ATT&CK

- T1596 Search Open Technical Databases
- T1587 Develop Capabilities
- T1585 Establish Accounts
- T1195 Supply Chain Compromise
- T1199 Trusted Relationship
- T1204.002 Malicious File
- T1059 Command and Scripting Interpreter
- T1027 Obfuscated Files or Information
- T1027.003 Steganography
- T1036 Masquerading
- T1140 Deobfuscate/Decode Files or Information
- T1685 Disable or Modify Tools
- T1552.001 Credentials In Files
- T1083 File and Directory Discovery
- T1005 Data from Local System
- T1119 Automated Collection
- T1132 Data Encoding
- T1567 Exfiltration Over Web Service
- T1048 Exfiltration Over Alternative Protocol

## Sources

- [GhostCommit Attack Hides Prompts Inside Images to Bypass AI Code Reviewers](https://cybersecuritynews.com/ghostcommit-attack-hides-prompts/)
- ['Ghostcommit' hides prompt injection in images to fool AI agents, steal secrets](https://www.bleepingcomputer.com/news/security/ghostcommit-hides-prompt-injection-in-images-to-fool-ai-agents-steal-secrets/)
- [GhostCommit Technical Disclosure (ASSET Research Group)](https://asset-group.github.io/disclosures/ghostcommit/)
- [asset-group/ghostcommit — Proof of Concept and Decoder](https://github.com/asset-group/ghostcommit)
- [Researchers hid a prompt injection inside a PNG, and AI fell for it](https://www.digitaltrends.com/cool-tech/researchers-hid-a-prompt-injection-inside-a-png-and-ai-fell-for-it/)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1231
