What happens to an AI server exposed to the internet
Attackers arrive already knowing the target.
For every source that ran inference on a decoy, we measured the time from its first request to its first inference request. The median is {{ f.arrival.p50 }} h: for half of them, the very first request was the inference itself. Nine in ten got there within {{ f.arrival.p90 }} h. High-severity attempts (code execution, server-side fetches, secret theft) look the same: {{ f.arrival.highFirst }} of {{ f.arrival.highOf }} sources made theirs in their first hour.
limits First contact is per address. Whatever found the endpoint (another address, a scanning service, shared scan data) is invisible here. That is the finding, not a gap in it.
what to do Do not wait for reconnaissance to alert on. An exposed inference API is used by someone who found it elsewhere: put authentication in front of it before it is reachable.
MCP servers get enumerated, almost never used.
{{ f.mcp.reached }} sources reached an MCP listener. {{ f.mcp.enumerated }} ({{ f.mcp.enumPct }}) spoke the protocol well enough to enumerate what the server offers. Tool calls in the whole window: {{ f.mcp.calls }}, from {{ f.mcp.callers }} of those sources. Along the way, {{ f.mcp.hijack }} tried to post into a session another source had opened, and {{ f.mcp.mismatch }} sent a protocol version that contradicted their own handshake, which is the mark of a hand-rolled client rather than an SDK.
limits Whether a tool gets called depends on what is offered; what these decoys offer may not tempt every actor.
what to do Enumeration hands your tool inventory to anyone who can reach the endpoint. Require authentication on MCP endpoints, and log enumeration requests: they come before any call.
Only two kinds of AI API get used.
Inference ran on OpenAI-compatible APIs ({{ f.used.openai }} sources) and Ollama ({{ f.used.ollama }}). Every other framework together: {{ f.used.otherInfer }}. Reaching is not using: of the {{ f.used.openaiReached }} sources that reached an OpenAI-compatible API, {{ f.used.openaiPct }} ran inference on it; for Ollama it was {{ f.used.ollamaPct }} of {{ f.used.ollamaReached }}. TGI was reached by {{ f.used.tgiReached }} sources and used by {{ f.used.tgiInfer }}.
limits These were open, unauthenticated decoys. Our reading, not a measurement: abuse tooling speaks the OpenAI and Ollama APIs, not every server's own.
what to do If anything on a box is exposed, make sure it is not an unauthenticated OpenAI-compatible or Ollama API.
Code execution goes after the notebooks, not the models.
{{ f.notebooks.total }} sources attempted code execution or a server-side fetch. The largest group, {{ f.notebooks.top.sources }}, {{ f.notebooks.top.label }}. Code execution went for the notebook and job runners that sit beside models on ML hosts; the full breakdown is alongside.
limits These are attempts. The decoys run nothing, so nothing here could succeed or fail.
what to do Never expose Jupyter or a Ray dashboard: on an ML box they are the code-execution path.
Stolen-key traffic is a few loud actors.
{{ f.keys.openaiSources }} sources presented OpenAI-format keys, and a single one of them sent {{ f.keys.openaiShare }} of those {{ f.keys.openaiEvents }} requests. {{ f.keys.other }} sources presented keys in no format we recognise. No key matched the documented formats of: {{ f.keys.absent }}.
limits Only a key's format is counted. No key is ever tested or stored.
what to do Request volume says little about how many people hold a key. Rotate any key that has sat in a config file reachable from the internet.
They come back, often on a schedule.
{{ f.ret.r2 }} of {{ f.ret.sources }} sources were seen on two or more days, {{ f.ret.r7 }} on seven or more, {{ f.ret.r30 }} on thirty or more; the most persistent on {{ f.ret.maxDays }} days. Of {{ f.ret.busy }} sources with twenty or more requests, {{ f.ret.locked }} ({{ f.ret.lockedPct }}) send 80% or more of their traffic in a single hour of the day, the signature of a scheduled job, and those hours cover {{ f.ret.lockedHours }} of the 24.
limits A return means the same address. A source that rotates addresses looks like many sources.
what to do Expect scheduled re-scans. A service hidden for a day will be found again.
Zero is a measurement.
What is being sent to AI endpoints
Which clients are sending it
A JA4H names the client software's header shape, not who runs it. Its first part is readable and is spelled out above each fingerprint. The header count leaves out Cookie and Referer, and the language is the first four letters of the Accept-Language header with dashes removed, as JA4H records it.
{{ p.s }} Browsers send Accept-Language; most HTTP libraries do not. After the readable part, b hashes the header names in order; c and d hash cookie names and values, so they are twelve zeros when no cookie was sent and are left off when one was. JA4H is part of FoxIO's JA4+ suite, licensed under the FoxIO License 1.1; JA4+ is a trademark of FoxIO. These fingerprints are computed by our own implementation, for non-commercial research.
What the endpoints see
How many distinct sources asked for each model by name. The faint bar is requests: where it runs long, a few sources asked often. Only the first row is checked for robustness; the order below it is approximate.
Which kinds of AI endpoint were reached, and by how many distinct sources. Ranked by requests instead, a few loud sources would reorder this board.
Each request is counted once, by the furthest step it reached.
One verdict per request, {{ v.total }} in all. On a linear scale everything under ten thousand would vanish; under a thousand is marked.
Test prompts that tooling sends to check an endpoint, matched by shape. The text itself is never published.
Which provider's key format arrived in a request, by distinct sources. Only the format is recorded, never the key.
When each of the loudest sources sends: its requests by hour of day and by weekday over the whole window, and on how many days it was seen. A source is one address, never a person; the network type is where traffic arrived from, often a relay or a rented host.
Method: how every number here is made
Decoy AI endpoints that answer like common inference servers (Ollama, vLLM, TGI, OpenAI-compatible APIs and others), notebook and job runners, and MCP servers. They respond realistically, run nothing an attacker sends, and make no outbound connection. The published window runs from {{ m.from }} to {{ m.to }}: {{ m.events }} requests from {{ m.sources }} distinct sources.
Success: nothing runs, so an attempt can never be shown to have worked. Reconnaissance from other addresses, or from shared internet-scan data. Anything behind authentication. Timing finer than a second. Who a source is: an address is often a relay, a rented host or a compromised machine.
The instrument changed on these days. A trend that crosses one compares two different setups.
{{ m.corr.dshield }} of {{ m.corr.sources }} sources ({{ m.corr.dshieldPct }}) also appear in DShield's current list of sources reported by other sensors. {{ m.corr.asnDrop }} came from networks on Spamhaus ASN-DROP; {{ m.corr.scanners }} from research scanners that publish their ranges.
DShield data: {{ m.corr.attribution }}
corroboration.json could not be loaded; nothing is shown rather than an old figure.
honeyprompt, independent AI-security research, honeyprompt.ai, data {{ m.from }} to {{ m.to }}. Data files: stats.json, meta.json, corroboration.json.
Country and network-number lookups use IP Geolocation by DB-IP (db-ip.com), licensed CC BY 4.0. Network kinds come from operators' own published address ranges, collected by the MISP warninglists project (CC0). Overlap figures use DShield data from the SANS Technology Institute, Internet Storm Center (isc.sans.edu).
Disclaimer: scope & data handling
honeyprompt is an independent AI-security research project. It operates a fleet of decoy AI endpoints and records how automated systems attempt to abuse exposed AI infrastructure. Everything published here is aggregate classification of that observed traffic.
Processing rests on legitimate interest (Art. 6(1)(f) GDPR) in securing infrastructure and conducting security research. Source addresses reach this site only as unsolicited inbound connections.
Privately, on access-controlled infrastructure, with encrypted backups. They are never published, never used to identify individuals, and never shared or sold.
Research records are kept for as long as the research runs. Erasure of an address may be requested at any time, via the route under Contact.
Nothing an attacker wrote is shown. Every word on these pages comes from a fixed vocabulary, and anything rendered is inert plain text.
Classification is automated and may contain errors. Figures describe observed probe traffic, not confirmed compromise — and are not an accusation against any named organisation.
Network operators may request context or correction; data subjects may request erasure. This project is run independently — requests may be directed to abuse at this domain.