Honeypotting username enumeration: a Cloudflare Snippet for /u/*.json scans

AI-generated summary

hhf.technology addresses the issue of scanners probing Discourse forums via /u/<name>.json to enumerate existing usernames. These probes consume server resources and leak information by revealing which accounts exist based on response codes. To mitigate this, the author shares a Cloudflare Snippet designed to intercept these requests at the edge.

The solution serves a “believable but fake” profile with a 200 status code to scanners, including a stable ID, join date, trust level, post count, and a dummy email with a canary string. This approach keeps the origin server free of these requests, thereby reducing load without blocking legitimate traffic. Real visitors are identified by session cookies, same-site referers, Accept: text/html headers, or API keys and are passed through to the origin untouched.

Key features include:

  • Edge Handling: No origin changes, no KV storage, and no additional Workers required; it uses only one snippet slot.
  • Monitoring: Hits are logged to New Relic with detailed metadata (IP, ASN, location, HTTP/TLS version, user agent, and probed username). A provided dashboard and NRQL queries help identify persistent scanners.
  • Deployment Notes: The documentation specifies that the matches operator requires a Cloudflare Business plan (suggesting wildcard as an alternative) and that two placeholders in the New Relic import must be replaced for success.

The author also notes that while Discourse’s built-in hide user profiles from public setting is often the preferable solution, it was not feasible for their specific use case. Following deployment, they observed an immediate decrease in server load.

My discourse forum gets this like crazy scanners: a bot walks a wordlist against /u/<name>.json, collects the 404s, and learns which usernames exist. Each probe costs a Unicorn worker and hands the scanner a free answer.

put together a small Cloudflare Snippet that answers those probes at the edge with a believable but fake profile — 200, a stable id derived from the username, join date, trust level, post count, even a fake email address carrying a canary string. Real visitors pass straight through untouched: a session cookie, a same-site referer, Accept: text/html or an API key all mean “leave this alone”. The origin never sees a probe, so the change is less load, not more.

Hits are logged to New Relic with IP, ASN and network name, country, city, edge colo, HTTP/TLS version, user agent and the username that was probed. There’s an eleven-widget dashboard you can import, and NRQL for “who keeps coming back”.

One snippet slot. No KV, no Worker, no origin changes, no blocking.
still you have 4 left and can utilized with other sites in your account.

Repo: GitHub - hhftechnology/cloudflare-honeypot: Cloudflare Snippet honeypot for user-enumeration scans (/u/*.json): fake 200 profile, New Relic logging, zero origin load · GitHub

The docs cover the Cloudflare rule (note: the matches operator needs Business — use wildcard), the New Relic import (two placeholders must be replaced or it fails), and the Discourse caveats — including the case where the built-in hide user profiles from public setting is simply the better answer. but for me this was not possible.

i hope this helps someone. our server load has decreased within an hour of deployment.