Aller au contenu
← Tous les articles

Backend1 min de lecture

Une API de contact qui résiste au spam, sans captcha

Champ piège, limitation de débit et délai minimal de saisie : trois défenses discrètes qui arrêtent l’essentiel des robots sans pénaliser les visiteurs.

Graphe de nœuds reliés par de fins traits bleus sur fond noir
Sommaire

Un captcha fait payer aux humains le coût des robots. Pour un formulaire de contact, trois mesures simples suffisent presque toujours.

Le champ piège

Un champ invisible pour les humains, mais présent dans le HTML. Un robot qui remplit tout le formulaire se dénonce. Attention à l’accessibilité : le champ doit être retiré de l’ordre de tabulation et ignoré par les lecteurs d’écran.

TypeScript
<div aria-hidden="true" className="absolute -left-[9999px]">
  <label htmlFor="website">Ne pas remplir</label>
  <input id="website" name="website" tabIndex={-1} autoComplete="off" />
</div>

Limiter le débit

Une fenêtre glissante par adresse IP, en mémoire : cinq messages par heure. Sur une instance unique, pas besoin de Redis.

TypeScript
const WINDOW_MS = 60 * 60 * 1000
const hits = new Map<string, number[]>()

export function allow(ip: string, now = Date.now()): boolean {
  const recent = (hits.get(ip) ?? []).filter((time) => now - time < WINDOW_MS)
  if (recent.length >= 5) return false
  hits.set(ip, [...recent, now])
  return true
}

Et derrière un proxy ?

L’adresse vue par l’application est celle du proxy. Il faut lire X-Forwarded-For, mais uniquement si la requête vient bien du proxy de confiance.

Le délai minimal

Un humain met plus de trois secondes à écrire un message. Un horodatage signé, glissé dans le formulaire au rendu, permet de rejeter les envois trop rapides sans rien stocker.

Bilan

  • L’essentiel des envois automatisés arrêté dès les premières semaines
  • Aucun faux positif signalé
  • Aucune dépendance externe
  • #API
  • #Sécurité

Partager

  • Treillis de points lumineux sur un halo bleu profond

    Backend1 min de lecture

    Chercher dans sa documentation avec PostgreSQL

    Avant d’ajouter un moteur de recherche à l’infrastructure, la recherche plein texte de PostgreSQL couvre souvent le besoin : accents, pertinence, droits d’accès.

  • Réseau clairsemé de nœuds bleus et de liaisons fines

    Backend1 min de lecture

    PostgreSQL : paginer sans OFFSET

    OFFSET relit toutes les lignes qu’il saute. La pagination par curseur garde un temps de réponse constant, même à la page mille.

  • Grille en perspective qui file vers un horizon bleu profond

    Infra & DevOps2 min de lecture

    Déployer sans coupure avec Docker Compose et Nginx

    Pas besoin d’un orchestrateur pour mettre à jour une application sans interrompre ses visiteurs : deux conteneurs, une sonde de santé et un rechargement de Nginx suffisent.

Un projet, une question ?

Cet article vous a donné une idée, ou vous bloquez sur un problème proche ? Écrivez-moi, je réponds à chaque message.