Context
Security audit flagged public-facing POST endpoints have no rate limiting:
POST /api/applications — apply form
POST /api/feedback — feedback form
/sign-in / /sign-up via Clerk (handled by Clerk, not by us)
Trivially spammable. An attacker can fire thousands of bogus applications or feedback submissions.
Options
-
Cloudflare WAF Rate Limiting Rule (recommended) — set up in dashboard under Security → WAF → Rate limiting rules. No code change needed. Rule: 10 requests per minute per IP on those paths.
-
Cloudflare Workers Rate Limiting API — [[unsafe.bindings]] type = "ratelimit" in wrangler.toml, then env.RATE_LIMITER.limit({ key: ip }) in handler. Code change but no KV needed.
-
KV-backed counter — spin up a KV namespace, track per-IP counters with TTL. More code, more moving parts.
Recommend Option 1 for simplicity. Takes ~5 minutes in the dashboard, no deploy.
Paths to cover
Start with:
POST /api/applications — limit 5/hour/IP (generous; people rarely re-submit)
POST /api/feedback — limit 10/hour/IP
POST /api/profile — limit 20/hour/IP (users may edit a few times)
Out of scope
Clerk auth endpoints are already rate-limited by Clerk.
Context
Security audit flagged public-facing POST endpoints have no rate limiting:
POST /api/applications— apply formPOST /api/feedback— feedback form/sign-in//sign-upvia Clerk (handled by Clerk, not by us)Trivially spammable. An attacker can fire thousands of bogus applications or feedback submissions.
Options
Cloudflare WAF Rate Limiting Rule (recommended) — set up in dashboard under Security → WAF → Rate limiting rules. No code change needed. Rule: 10 requests per minute per IP on those paths.
Cloudflare Workers Rate Limiting API —
[[unsafe.bindings]] type = "ratelimit"in wrangler.toml, thenenv.RATE_LIMITER.limit({ key: ip })in handler. Code change but no KV needed.KV-backed counter — spin up a KV namespace, track per-IP counters with TTL. More code, more moving parts.
Recommend Option 1 for simplicity. Takes ~5 minutes in the dashboard, no deploy.
Paths to cover
Start with:
POST /api/applications— limit 5/hour/IP (generous; people rarely re-submit)POST /api/feedback— limit 10/hour/IPPOST /api/profile— limit 20/hour/IP (users may edit a few times)Out of scope
Clerk auth endpoints are already rate-limited by Clerk.