discord-botlists.

discord-botlists docs · archived reader

Core Concepts

Webhook security

How the server rejects fake votes, floods and brute force.

Anyone who discovers your webhook URL could POST fake votes. The server defends against that with secure defaults: secrets are required, per-IP rate limiting and brute-force lockout are always on, and HMAC payload signing is supported per list.

security options

const lists = new Botlists({
  webhook: {
    port: 8080,
    secret: {
      'top.gg': 'shared-secret-for-topgg',
      'botlist.me': 'another-secret',
    },
    security: {
      // HMAC-SHA256 signing keys per list. when present, requests from that
      // list must carry a valid signature in x-signature-256 /
      // x-hub-signature-256 / x-signature.
      hmac: { 'top.gg': 'webhook-signing-key' },

      // per ip rate limit (default 30/min). extra requests get 429.
      rateLimit: { max: 30, windowMs: 60_000 },

      // ban an ip after N consecutive auth failures (default 10),
      // for M ms (default 15 minutes). banned ips get 403.
      banAfterFailures: 10,
      banDurationMs: 15 * 60_000,

      // only these lists may POST at all. others get 403.
      allowedLists: ['top.gg', 'botlist.me', 'discordbotlist.com'],

      // set true behind nginx/cloudflare so rate limits use the real ip.
      trustProxy: true,

      // only for local testing: accept unsigned posts.
      requireSecret: false,
    },
  },
});
ThreatDefenseResponse
Fake votes (no secret)Secret required on every POST401
Replayed/forged payloadsHMAC-SHA256 signature check401
Secret brute forceFailure counter per ip403 ban after 10
Request floodsPer ip token bucket429 + Retry-After
Giant payloads512 KB body limit413
Unlisted sourcesallowedLists check403
NoteThe server throws at start() when requireSecret is true (the default) and no secret was configured. This is intentional: an open webhook endpoint will receive fake votes within hours of going public.