My App

ADR-05: Anti-spam

Stratégie multi-couche contre l'abus de signalement

Contexte

Le scénario d'abus principal : quelqu'un prend en photo le QR code et spamme des signalements depuis chez lui. Chaque faux signalement peut déclencher un WhatsApp (~0.05€) et polluer le dashboard. Il faut bloquer sans gêner les utilisateurs légitimes.

Décision

Défense en profondeur — 5 couches complémentaires.

Couche 1 : Token rotatif (passif)

Le token dans l'URL du QR code expire après 7 jours. Un photo prise aujourd'hui ne fonctionnera plus dans une semaine.

ScénarioRésultat
Scan sur place (token valide)✅ Accès autorisé
Photo prise il y a 2 jours✅ Encore valide
Photo prise il y a 8 jours❌ Token expiré → message d'erreur

Couche 2 : Rate limiting par IP

Limiter le nombre de signalements par adresse IP sur une fenêtre glissante.

LimiteFenêtreAction
3 signalements15 minutesBlocage temporaire
10 signalements1 heureBlocage 1h
20 signalements24 heuresBlocage 24h + alerte admin

L'IP est hashée (SHA-256 + salt) en base — pas de stockage d'IP en clair (RGPD).

Couche 3 : Device fingerprinting

Un fingerprint du device (combinaison User-Agent + résolution + timezone + langue) est généré côté client et hashé. Même limites que l'IP mais par device.

const fingerprint = await generateFingerprint({
  userAgent: navigator.userAgent,
  screen: `${screen.width}x${screen.height}`,
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
  language: navigator.language,
});

Couche 4 : Cooldown par device

Après un signalement réussi, le même device ne peut pas signaler le même WC pendant 10 minutes. Stocké dans un cookie court (httpOnly) + vérifié côté serveur.

Couche 5 : Détection de patterns anormaux

Analyse côté serveur des patterns suspects :

PatternSeuilAction
Même fingerprint, WC différents5 WC en 10 minBlocage + flag
Même IP, même texte libre2 identiquesRejet du duplicata
Volume anormal sur un WC10 signalements/heureAlerte admin + auto-ignore

Couches NON retenues

CoucheRaison du rejet
CAPTCHA (reCAPTCHA, hCaptcha)Friction trop forte pour un parcours de 10 secondes
Géolocalisation GPSNécessite la permission explicite, taux de refus élevé
Inscription obligatoireContraire au principe d'anonymat et de rapidité
Vérification par SMSCoût, friction, nécessite un numéro de téléphone

Conséquences

  • Positif : 5 couches complémentaires, difficile de contourner toutes
  • Positif : Aucune friction pour l'utilisateur légitime (tout est invisible)
  • Positif : Pas de données personnelles stockées (IP hashée, fingerprint hashé)
  • Attention : Le fingerprinting n'est pas parfait (navigation privée, VPN)
  • Attention : Les faux positifs sont possibles (Wi-Fi partagé → même IP)
  • Attention : L'agrégation WhatsApp (ADR-03) sert aussi d'anti-coût passif

On this page