Blog

Protecting APIs and forms against abuse and spam

Updated: 12 min read
securityrate-limitinganti-spamvalidationapiturnstile

Contact forms, login endpoints, and public APIs are frequent abuse targets: spam, brute force, scraping, and automated submissions. Effective protection combines several layers; none alone is enough.

This article describes a layered approach to protecting forms and endpoints in Astro, Laravel, and Node.js applications — the same pattern this portfolio uses in production.

Protection layers

  1. Rate limiting: limit requests per IP in a time window.
  2. Honeypot: hidden field bots fill and humans do not.
  3. Form timing: detect submissions faster than a human (< 3.5s).
  4. Origin check: validate Origin/Referer in production.
  5. Schema validation: Zod or equivalent on the server.
  6. Sanitization: clean inputs before processing or storing.
  7. Optional CAPTCHA: Cloudflare Turnstile when volume justifies it.

Rate limiting

Apply on sensitive public endpoints:

  • Login and registration: 5 attempts per IP per minute.
  • Password reset: 3 per IP per hour.
  • Contact form: 5 per IP per minute.
  • Unauthenticated APIs: depends on the use case.

In-memory implementation for a single process; Redis when there are multiple replicas. Respond with 429 Too Many Requests and Retry-After header.

Honeypot

Hidden field with CSS (display: none or position: absolute; left: -9999px). Bots fill it automatically; humans do not see it. If it arrives with a value, reject silently (respond 200 without processing, to avoid tipping off the bot).

Form timing

Record a timestamp when rendering the form (hidden field or session). On POST, reject if elapsed time is under 3–4 seconds. Bots submit instantly; humans need at least a few seconds to read and complete.

Server-side validation

Schemas with Zod (or equivalent) on every API endpoint:

  • Strict types: email as email, phone with format, max length.
  • Explicit required vs optional fields.
  • Reject payloads with unexpected fields (strip or reject).
  • Generic error messages to the client; detail only in server logs.

Sanitization

  • Strip HTML from plain text fields.
  • Normalize whitespace and control characters.
  • Truncate strings that exceed max length.
  • Never interpolate user input into SQL queries or templates without escaping.

Origin check

In production, validate that the Origin or Referer header matches the site domain. Reject requests from unknown domains. Not foolproof (can be forged), but filters basic bots and cross-origin scripts.

Cloudflare Turnstile

When spam volume justifies extra friction, Cloudflare Turnstile is lightweight and privacy-friendly. Configure with TURNSTILE_SITE_KEY (public) and TURNSTILE_SECRET_KEY (server). The server verifies the token before processing the form.

Full flow on an endpoint

  1. Rate limit check → 429 if exceeded.
  2. Honeypot check → silent 200 if filled.
  3. Form timing check → 400 if too fast.
  4. Origin check → 403 if invalid origin.
  5. Turnstile verification (if configured) → 400 if invalid.
  6. Zod validation → 400 with field errors.
  7. Sanitization → process.

Common mistakes

  • Relying only on frontend validation.
  • Rate limiting only on login, not contact or webhooks.
  • Visible honeypot or accessible tabindex (screen readers fill it).
  • Responding 403 to honeypot (the bot learns and adapts).
  • Logging full payloads with emails and phones (PII in logs).
  • In-memory rate limit with 3 replicas (each has its own counter).

Connect with security audit, cybersecurity, and REST APIs .

Frequently asked questions

Is a honeypot enough against bots?

Not alone. A honeypot filters basic bots, but combine it with rate limiting, form timing, and, in production, a CAPTCHA like Turnstile.

Where should you apply rate limiting?

On public endpoints: login, registration, password reset, contact forms, webhooks, and unauthenticated APIs. Per IP and, when applicable, per authenticated user.

Validate on frontend or backend?

Both, but backend is mandatory. Frontend validation improves UX; backend validation is what matters for security.

Turnstile or reCAPTCHA?

Cloudflare Turnstile is lightweight, privacy-friendly, and integrates smoothly. reCAPTCHA v3 works but depends on Google. The choice depends on your stack and privacy policy.

Does in-memory rate limiting scale?

For a single process, yes. With multiple replicas you need Redis or another shared store. In development, memory is enough.