genai
SECURITY LAB
IncidentsData exfiltration

AgentFlayer: A Poisoned Document Made ChatGPT Search Google Drive for API Keys

High severityVendor vulnerabilityAugust 2025LLM01: Prompt InjectionLLM02: Sensitive Information Disclosure
Status: Research demonstration shown at Black Hat USA 2025; Zenity reported it to OpenAI, which implemented fixes
Sources checked October 2026
On this page

The user asked for a summary. The file asked for their API keys, and ChatGPT followed the file.

WhenAugust 2025 (Black Hat USA)
TargetChatGPT Connectors (Google Drive)
VendorOpenAI
ResearchersTamir Ishay Sharbat, Michael Bargury (Zenity Labs)
TechniqueHidden instructions in a document; image-URL exfiltration via Azure Blob Storage
StatusResearch demo; reported to OpenAI, which implemented fixes
Attack flow
  1. 1Attacker hides instructions in 1px white text inside a business-looking document
  2. 2The victim asks ChatGPT to summarise it; ChatGPT searches their Google Drive for API keys instead
  3. 3The keys leave in an Azure-hosted image URL that passes OpenAI's url_safe check

What happened

On 6 August 2025, Zenity Labs researcher Tamir Ishay Sharbat published AgentFlayer, a proof of concept against ChatGPT Connectors, the feature that lets ChatGPT search services a user links to it, such as Google Drive, SharePoint, OneDrive and GitHub. Sharbat and Zenity CTO Michael Bargury presented the research at Black Hat USA 2025. The attack needs one poisoned document. When the victim gives it to ChatGPT and asks for a summary, instructions hidden in the file make ChatGPT search the victim's connected Google Drive for API keys and send them to the attacker. The victim clicks nothing, and the hidden text tells ChatGPT not to mention the search. This was a research proof of concept; no source reports it being used against real victims. Zenity reported it to OpenAI, which implemented fixes.

How the attack worked

The document looked like an ordinary business file. The instructions sat inside it in 1-pixel white text: invisible to a person reading the page, plain text to the model. Zenity points out that people routinely upload files from outside sources to ChatGPT for a summary, and that a malicious insider could poison documents they already have access to and spread them to colleagues. Bargury told Wired an attacker needs only the victim's email address to share the document with them.

Once ChatGPT read the file, the hidden text told it to drop the summary, search the connected Drive for API keys, and keep the change of plan from the user. It framed the request as a favour for a developer up against a deadline: social engineering aimed at the model, not at a person.

To get the keys out, the instructions had ChatGPT write a markdown image whose URL carried the keys as query parameters. When the chat client renders that image, the browser requests the URL and whoever runs the server receives the parameters. Wired reported that the technique could not carry out whole documents, but API keys are short and worth a lot.

The allowlist gapChatGPT already checked image URLs against an endpoint called url_safe before rendering them, and it blocked the researchers' first test server. Images hosted on Azure Blob Storage passed the check. With the storage account's request logs sent to Azure Log Analytics, every image request, parameters included, landed in a log the attacker could read.

Root cause

Three conditions sat in one product. The document was untrusted, but its text reached the model in the same context as the user's request, with nothing marking it as data rather than instructions. ChatGPT held live search access to the user's Drive and could use it mid-task even though a summary of one file never needed it. And the client fetched images from any URL the safety check approved, so model output could carry data out. That check let through a public cloud storage domain, which serves content for anyone who opens an account. A trusted domain is not the same as a trusted destination.

What a test would have caught

An indirect-injection test that hides instructions in a document, asks for a plain summary and logs every tool call would have shown a Drive search the request never asked for. A second check, on whether the assistant will emit an external image URL with data in its query string, would have found the exfiltration channel. Running that check against cloud storage hosts, not only an obviously hostile server, would have exposed the gap in the url_safe check too.

How to prevent it

  • Treat uploaded and connector content as data. Fence it off from instructions, and flag hidden text such as tiny or white fonts before the model reads it.
  • Tie tool calls to the user's request. Summarising one file does not need a search of the whole Drive; ask the user before a connector call the request did not imply.
  • Close the image channel. Do not auto-render model-written image URLs to outside hosts. Stripping the query string is not enough, since data can ride in the path too, and a domain allowlist on its own fails on shared storage domains.
  • Keep secrets out of document stores. API keys belong in a secrets manager, not in files an assistant can search.

Feel it yourselfThe replay lab puts you in front of a docs copilot that reads documents shared in by outside partners. Find out how one of them can make it fetch and print a confidential figure its user never asked for.

FAQ

What was the AgentFlayer attack on ChatGPT?

A proof of concept from Zenity Labs, published in August 2025 and shown at Black Hat USA. A document carrying hidden instructions, given to ChatGPT for a summary, made ChatGPT search the user's connected Google Drive for API keys and send them to the researchers through an image URL. It was a research demonstration, and OpenAI implemented fixes after Zenity reported it.

How did the data leave ChatGPT without a click?

The hidden instructions had ChatGPT write a markdown image whose URL carried the keys as query parameters. Rendering the image makes the browser request that URL. OpenAI's url_safe check blocked the researchers' first test server, but images on Azure Blob Storage passed it, and Azure's request logs recorded the parameters for the attacker to read.

How do you protect an AI assistant with connectors from poisoned documents?

Treat uploaded and connected content as data, not instructions. Ask the user before a connector search the request did not call for, do not let the client auto-render model-written image URLs to outside hosts, and keep API keys out of files an assistant can search.

Replay this attack
Assess a docs copilot that summarises documents shared in by outside partners and work out how one of them can make it fetch and print a confidential deal-desk code its user never asked for, the same poisoned-file, ordinary-request pattern AgentFlayer turned against ChatGPT's Google Drive access.
Open the live lab
A live, sandboxed lab. It recreates the technique, not this exact product.