Engagement Report: Eleven Honeypot Endpoints That Never Sent a Response

BotToll's own documented trap endpoint, and ten other legacy honeypot routes alongside it, were registered with empty handlers that hung every request instead of returning the instant 402 the README promises, verified live and fixed.

Eighth sample engagement report, on BotToll, a scraper and AI-crawler deterrence layer: fingerprinting, progressive rate-limiting, invisible honeypot traps, and an on-chain toll mechanism for unlicensed bots. This repo has no automated test suite at all, so the verification here is direct: run the server for real, hit its own documented endpoints with the exact user agents it's built to catch, and read what actually comes back.

Scope and Objective

Target: the full Express toll engine in server.ts, with particular attention to the honeypot routes the README instructs site owners to deploy, and the GenAI-powered "Protocol Neural Poison" data-pollution feature.

Objective: since there is no npm test here, confirm the project builds clean (tsc --noEmit), then run the live dev server and send real requests, with real bot user agents, against every documented trap and against the progressive deterrence ladder, to see whether the code's actual behavior matches what the README and features.md claim.

Findings

1. High: eleven documented honeypot routes had empty handlers and hung instead of rejecting. The README's own "USAGE STEPS" section instructs site owners to wire an invisible link into their HTML pointing at /api/data-verify, described as "The Trap," with the claim that "invisible honeypots trigger immediate 402 rejection." The actual handler for that route, and ten sibling routes serving other sites in the same codebase, was this:

app.get("/api/data-verify", (req, res) => { /* ... fiamma ... */ });
app.get("/api/v1/spectral-anchor.png", (req, res) => { /* ... fiamma ... */ });
app.get("/api/sys-integrity-v1", (req, res) => { /* ... generic ... */ });
app.get("/api/v1/seed-vault-anchor.png", (req, res) => { /* ... futurebudz ... */ });
app.get("/api/genetic-metadata-v1", (req, res) => { /* ... futurebudz ... */ });
app.get("/api/v1/ghost-anchor.png", (req, res) => { /* ... ghost ... */ });
app.get("/api/v1/prompt-integrity-metadata", (req, res) => { /* ... ghost ... */ });
app.get("/api/v1/mdrn-anchor.png", (req, res) => { /* ... mdrn ... */ });
app.get("/api/v1/studio-integrity-metadata", (req, res) => { /* ... mdrn ... */ });
app.get("/api/v1/vault-anchor.png", (req, res) => { /* ... pcc ... */ });
app.get("/api/v1/vending-machine-metadata", (req, res) => { /* ... pcc ... */ });

Every one of these bodies is a comment and nothing else. No res.send, no res.json, no res.end. In Express, a handler that never calls a response method never finishes the request. A bot hitting any of these eleven routes doesn't get a 402. It gets silence, held open until the client or the platform's own timeout gives up. That's the opposite of deterrence: the connection stays occupied and the bot learns nothing, instead of getting the instant, unmistakable rejection the README promises.

2. Medium: the AI data-poisoning engine is hardcoded to a model Google retired over a year ago. "Protocol Neural Poison," the feature both the README and features.md headline as "Powered by Gemini-1.5-Flash," calls client.models.generateContent({ model: "gemini-1.5-flash", ... }). Google's own Gemini API changelog lists gemini-1.5-flash among the models shut down on September 29, 2025. In any deployment with a real GEMINI_API_KEY configured, every call to this model now fails, and the code's own catch block routes the failure into a generic fallback string, [ERROR_FALLBACK]_DATA_CORRUPTION_EVENT_${scenario}_${Date.now()}, instead of the "unique, realistic leaked data per session" the project advertises. Without an API key, the code already falls back to a static random-hex string by design, so this bug is invisible in demo mode and only shows up once someone actually wires in the key the feature exists for.

Verification

No test suite exists in this repo. package.json has no test script, and the only check at all is "lint": "tsc --noEmit". Everything below is a live run against the actual server.

Typecheck, clean on both the original and the fixed code:

$ npm run lint
> [email protected] lint
> tsc --noEmit
(no output, exit 0)

Before the fix, hitting the README's own documented trap with a 5-second cap:

$ time curl -s -i --max-time 5 -A "GPTBot/1.0" http://localhost:3000/api/data-verify
HTTP 000  (no response, connection open for the full 5s before curl gave up)
real 5.015s

After wiring all eleven routes through the same fingerprint-and-402 logic the file's two "Universal Traps" already used (an image/png pixel response for the -anchor.png paths, a JSON rejection for the metadata/integrity paths):

$ curl -s -i --max-time 5 -A "GPTBot/1.0" http://localhost:3000/api/data-verify
HTTP/1.1 402 Payment Required
{"error":"Access Denied","message":"Integrity validation failed."}
real 0.011s

$ curl -s -i --max-time 5 -A "GPTBot/1.0" http://localhost:3000/api/sys-integrity-v1
HTTP/1.1 402 Payment Required
real 0.009s

$ curl -s -A "GPTBot/1.0" http://localhost:3000/api/v1/ghost-anchor.png -o anchor.png -w "HTTP %{http_code}, bytes: %{size_download}\n"
HTTP 402, bytes: 68

Independently of the honeypot fix, the progressive deterrence ladder itself was confirmed correct. Ten requests from a fresh bot fingerprint (claude-bot-verify-test user agent, matched against the project's AI_BOTS list) each added 5,000 tracked bytes and passed through under the 51,200-byte toll threshold. The eleventh request pushed tracked bytes to 55,000, crossed the threshold, and returned the documented "Unlicensed Scraper Detected" 402 with a computed delay:

$ time curl -s -i -A "claude-bot-verify-test" http://localhost:3000/
HTTP/1.1 402 Payment Required
{"error":"Unlicensed Scraper Detected","contract":"...","toll_due":"0.01 BTC / 1 ETH", ...}
real 2.388s

That delay matches the code's own formula exactly: 2000 + (55000 - 51200) / 10 = 2380ms. /api/toll-dashboard afterward showed two tracked fingerprints and three logged incidents, including the newly-fixed LEGACY_ANCHOR_TRIGGER, confirming the registry state lines up with what the live requests actually did.

Not verified in this pass: the live GEMINI_API_KEY path (no key configured in this environment, so the fix to the model string is confirmed correct against Google's current model lineup but not confirmed against a real API response), and the on-chain /api/payment/verify endpoint, which needs a real settled Ethereum transaction hash to exercise.

Mitigations and Next Steps

  1. Fixed: all eleven legacy trap routes now run through two small shared handlers (legacyAnchorTrap, legacyMetadataTrap) that mirror the project's own working Universal Trap pattern, each incrementing the hit fingerprint's tracked bytes, logging a real incident, and returning an immediate 402.
  2. Fixed: the Neural Poison model string is updated to gemini-3.8-flash, the Flash-line model Google's own changelog currently points new callers to, with the retired gemini-1.5-flash string left in a comment for the record. The matching "Powered by Gemini-1.5-Flash" branding lines in README.md and features.md are updated to match.
  3. Not fixed, flagged honestly: npm audit reports 15 vulnerabilities in the dependency tree (1 critical, 7 high), including a critical IP-spoofing advisory in proxy-addr, a transitive dependency of Express that feeds directly into req.ip, the value this tool's own fingerprinting hashes on every request. Worth a dedicated pass to confirm npm audit fix doesn't break the Vite/Express version pins before applying it, not folded into this one.
  4. Worth doing once a deployment target is picked: none of this was tested behind a real reverse proxy or Cloud Run-style ingress, where Express's trust proxy setting determines whether req.ip reflects the actual client or the proxy itself. The .env.example comments reference Cloud Run and AI Studio injection, which implies exactly that kind of deployment, so this is a real open question for whoever stands this up for real, not a bug confirmed in this pass.

GhostInThePrompt.com // Eleven honeypots promised an instant no. All eleven delivered silence instead.