Skip to content
honeyprompt logo honeyprompt research

Bots are hunting exposed AI. This is what they try — receipts, not rumors.

{{ srcBadge }} | {{ freshLabel }} · fetched {{ fetchedAgo }}s ago

What happens to an AI server exposed to the internet

Measured on decoy AI endpoints, {{ win }}. Counted in distinct sources, not requests. Definitions: Method.
{{ stateNote }}
finding · arrival

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.

{{ f.arrival.first }}
of {{ f.arrival.of }} sources that ran inference did it within their first hour of contact ({{ f.arrival.pct }})
"first contact" means from that address
finding · MCP

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.

{{ f.mcp.enumerated }}
sources enumerated the server
{{ f.mcp.callers }}
called one ({{ f.mcp.calls }} calls in total)
finding · what gets used

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.

reachedran inference
{{ s.label }} {{ s.reached }} · {{ s.infer }}
finding · code execution

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.

{{ r.label }}{{ r.sources }}
distinct sources per action
finding · stolen keys

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.

{{ f.keys.openaiShare }}
of OpenAI-format key requests came from one source
finding · return visits

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.

{{ f.ret.r2pct }}
of sources came back on a later day
null results · looked for, not seen

Zero is a measurement.

techniqueobservedwindowwhy it matters
{{ n.name }} {{ n.v }} {{ n.since }} {{ n.why }}
Every figure comes from the published data files, which are updated once a day (UTC). Distinct sources are counted by address and never published; see Method for definitions and limits.

What is being sent to AI endpoints

Request shapes, never addresses. A row appears only once at least {{ s.floor }} distinct sources have sent it; rows are ordered by sources, and only the first is checked for robustness. The clients behind them: Fingerprints. Definitions: Method.
JSON
{{ stateNote }}
request shapes
{{ s.shown }} shown · {{ s.below }} below the {{ s.floor }}-source floor, not shown · {{ s.shapesCut }} more past the 400-row limit, the fewest sources first
surfacemethodwhat it doestellssourcestop
{{ g.label }} · {{ g.n }} shapes
nothing above the floor in this window
{{ r.surfaceLabel }} {{ r.method }} {{ r.actionLabel }}{{ r.days }} {{ t.t }} {{ r.sources }} {{ r.shareTxt }}
"top" is the share of a row's requests from its single busiest source; {{ warnPct }} or more is marked.
The week is the last complete Monday-to-Sunday week (UTC). All-time rows carry first and last day seen. Every word in a row comes from a fixed vocabulary; nothing an attacker wrote is shown.

Which clients are sending it

Standard JA4H fingerprints of the software making the requests on the Feed, never addresses. A fingerprint appears only once at least {{ f.floor }} distinct sources have sent it; rows are ordered by sources, and only the first is checked for robustness. Definitions: Method.
JSON
{{ stateNote }}
client fingerprints · standard JA4H
{{ lead }} · captured since {{ f.since }} · {{ f.fpBelow }} below the floor · {{ f.fpCut }} more past the 400-row limit, the fewest sources first

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.

No published fingerprint matches. Below the {{ f.floor }}-source floor a fingerprint is not shown at all, so this does not mean it was never seen.
no fingerprint above the floor in this window
{{ w.t }}{{ w.sep }}
{{ p.s }}
surfaces{{ x.label }} {{ x.sources }}spread thinly: no surface reached by {{ f.floor }}+ of its sources
sourcestop {{ r.sources }} {{ r.shareTxt }} {{ r.days }}

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.

The week is the last complete Monday-to-Sunday week (UTC). All-time rows carry first and last day seen. A fingerprint is computed from header names and order, plus four letters of Accept-Language; nothing an attacker wrote is shown.

What the endpoints see

Counts over the whole window, ranked by distinct sources wherever the data allows, so one loud source cannot own a board. Definitions: Method.
{{ stateNote }}
model demand
the {{ md.n }} most-requested of the models these endpoints list · by distinct sources

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.

Model demand could not be read from this snapshot. Nothing is shown rather than a stale ranking.
#modelsourcestop
{{ r.rank }} {{ r.name }} {{ r.sources }} {{ r.shareTxt }}
distinct sources requests "top" is the share of a row's requests from its busiest source; 70% or more is marked.
surfaces
all {{ sf.n }} endpoint kinds · {{ sf.events }} requests · by distinct sources

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.

Surfaces could not be read from this snapshot.
#endpointsourcesrequeststop
{{ r.rank }} {{ r.label }} {{ r.sources }} {{ r.events }} {{ r.shareTxt }}
The accent bar is distinct sources, the faint bar requests. "unrouted" marks requests from the first day of capture, before each was tagged with its endpoint; "other" is a value outside the known list.
what they're doing
{{ i.total }} requests · one category each

Each request is counted once, by the furthest step it reached.

The intent breakdown could not be read from this snapshot.
{{ r.name }}furthest step: {{ r.steps }} {{ r.pctTxt }} · {{ r.count }}
verdicts
log scale · each grid line is ×10

One verdict per request, {{ v.total }} in all. On a linear scale everything under ten thousand would vanish; under a thousand is marked.

Verdicts could not be read from this snapshot.
{{ t.label }}
{{ r.label }} {{ r.count }}
canned prompts
{{ p.total }} requests matched a known prompt

Test prompts that tooling sends to check an endpoint, matched by shape. The text itself is never published.

Canned prompts could not be read from this snapshot.
{{ r.name }}
{{ r.count }}{{ r.pctTxt }}
{{ p.topTwoA }} and {{ p.topTwoB }} together are {{ p.topTwoPct }} of matches.
key formats presented
one square = {{ k.unit }}

Which provider's key format arrived in a request, by distinct sources. Only the format is recorded, never the key.

Key formats could not be read from this snapshot.
{{ r.label }}{{ r.events }} requests · top {{ r.shareTxt }} {{ r.sources }}
A source that presented more than one format counts in each row, so the rows do not add up to a total.
busiest sources
the {{ bs.n }} sources with the most requests · times in UTC

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.

Sources could not be read from this snapshot.
#sourcehour of day · 00 → 23weekdayseen
{{ r.rank }} {{ r.kind }} {{ r.cc }}{{ r.count }} requests {{ r.days }}{{ r.peakPct }} at {{ r.peak }} · {{ r.peakDayPct }} on {{ r.peakDay }}
A source seen on one day only is a burst, whatever its hours look like. Most requests in one hour across many days suggests a scheduled job; this page reports the counts, not the intent.
Every label on this page comes from a fixed vocabulary or the models these endpoints advertise; nothing an attacker wrote is shown.

Method: how every number here is made

What the decoys are, what they cannot see, and what each word means. What is published, what never is, and how addresses are held: the Disclaimer.
what we run

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.

what we cannot see

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.

definitions
{{ x.term }} {{ x.def }}
coverage changes

The instrument changed on these days. A trend that crosses one compares two different setups.

{{ c.d }}
seen elsewhere

{{ 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.

cite this

honeyprompt, independent AI-security research, honeyprompt.ai, data {{ m.from }} to {{ m.to }}. Data files: stats.json, meta.json, corroboration.json.

third-party data

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

What is collected, what is published, what never is, and how to reach us. How each number is made is on the Method page.

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.

{{ s.num }}
{{ s.name }}
{{ s.sub }}
the wall · addresses never cross it
private · access-controlled · encrypted backups
public · aggregate · rendered inert
what happens to each field of a request
publishedtransformed, then publishednever published
inboundbecomesstate
{{ f.field }}
→{{ f.becomes }}
{{ f.state }}
what we publish
·Categories, counts and verdicts
·A fixed vocabulary of tradecraft tags
·The kind of network (hosting, CDN, ISP or carrier, research scanner) where it is verified, and country; network names only for the busiest networks, each seen from many distinct sources
·An anonymized source id — stable, but never reversible to an address
what we never publish
·Raw prompt text or payloads
·Source IP addresses
·Any per-host identifier
·Anything that maps a published id back to an address
legal basis

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.

how addresses are held

Privately, on access-controlled infrastructure, with encrypted backups. They are never published, never used to identify individuals, and never shared or sold.

retention & erasure

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.

untrusted data

Nothing an attacker wrote is shown. Every word on these pages comes from a fixed vocabulary, and anything rendered is inert plain text.

accuracy

Classification is automated and may contain errors. Figures describe observed probe traffic, not confirmed compromise — and are not an accusation against any named organisation.

contact

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.

Provided “as is” for research and informational purposes · not legal advice · not affiliated with any cloud or model provider named in the data.
{{ pop.title }}
{{ pop.tag }}
{{ pop.lede }}
{{ pop.caps }}
{{ pop.rowsHead }}
{{ r.k }}{{ r.v }}
{{ pop.noteHead }}
{{ pop.note }}