Énumération de noms d'utilisateur par honeypot : un snippet Cloudflare pour les scans /u/*.json

Mon forum Discourse est soumis à ce type de scanners de manière intensive : un bot parcourt une liste de mots en interrogeant /u/<username>.json, collecte les erreurs 404 et déduit ainsi quels noms d’utilisateur existent. Chaque requête coûte un worker Unicorn et fournit au scanner une réponse gratuite.

J’ai élaboré un petit extrait Cloudflare qui répond à ces sondages au niveau de l’edge avec un profil plausible mais fictif — 200, un identifiant stable dérivé du nom d’utilisateur, la date d’inscription, le niveau de confiance, le nombre de messages, et même une adresse e-mail factice contenant une chaîne canari. Les visiteurs réels passent sans aucune modification : un cookie de session, un référent same-site, un en-tête Accept: text/html ou une clé API signifient tous « laissez passer ». L’origine ne voit jamais les sondages, ce qui se traduit donc par une réduction de la charge, et non par une augmentation.

Les hits sont journalisés dans New Relic avec l’IP, l’ASN et le nom du réseau, le pays, la ville, le colo de l’edge, la version HTTP/TLS, l’agent utilisateur et le nom d’utilisateur sondé. Il y a un tableau de bord à onze widgets que vous pouvez importer, ainsi que des requêtes NRQL pour identifier « qui revient sans cesse ».

Un seul slot d’extrait. Pas de KV, pas de Worker, aucune modification à l’origine, pas de blocage.
Il vous reste encore 4 slots que vous pouvez utiliser pour d’autres sites de votre compte.

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

La documentation couvre la règle Cloudflare (note : l’opérateur matches nécessite le plan Business — utilisez wildcard), l’import dans New Relic (deux espaces réservés doivent être remplacés sous peine d’échec) et les spécificités de Discourse — notamment le fait que le paramètre intégré masquer les profils utilisateur au public est simplement la meilleure solution. Mais dans mon cas, cela n’était pas possible.

J’espère que cela aidera quelqu’un. La charge de notre serveur a diminué dans l’heure suivant le déploiement.