Aller au contenu
Guide

Arrêtez la fraude à l'inscription avec 3 vérifications API, aucun captcha requis

| 7 min read

Les captchas nuisent à la conversion et les robots les résolvent de toute façon. Marquez chaque inscription avec des vérifications VPN, e-mail jetables et listes de blocage IP en moins de 120 ms, et ne défiez que les 5 % les plus performants.

Digital security shield representing signup fraud detection and scoring
Photo by Franck on Unsplash

Les robots sont moins chers que votre budget captcha. Une ferme de résolution commerciale efface reCAPTCHA v2 à environ 1 $ pour mille, donc un scraper qui veut 50 000 comptes jetables dépense moins en captchas qu'en VPS pour exécuter le script. Pendant ce temps, vos vrais utilisateurs rebondissent sur le puzzle à un taux de 3 à 15 %.

Une meilleure clôture est un score. Trois appels d'API vous donnent suffisamment de signal pour laisser passer 95 % des inscriptions sans friction ni contestation ou bloquer la tranche restante. Latence totale inférieure à 120 ms sur le P99.

Trois signaux, trois points finaux

Chaque inscription a une adresse IP et un e-mail. Cela suffit pour poser trois questions précises.

L'adresse IP est-elle un VPN, une sortie Tor ou un centre de données ?

Les inscriptions de vrais consommateurs proviennent rarement d'un bloc AWS CIDR. Un nœud de sortie Tor ne s'inscrit presque jamais pour un essai gratuit de votre SaaS. Le /v1/vpn-detect le point final vérifie les trois.

{
  "ip": "34.102.55.10",
  "is_vpn": true,
  "is_tor": false,
  "is_datacenter": true,
  "provider": "Google Cloud",
  "risk_score": 60
}

L'e-mail utilise-t-il un domaine jetable ?

Les fournisseurs jetables (mailinator, guerrillamail, tempmail) font tourner les boîtes de réception en quelques minutes. Si une inscription atteint un domaine jetable, l'utilisateur n'a aucune intention de recevoir un suivi. /v1/disposable-email/check signale plus de 700 fournisseurs connus ainsi que des modèles heuristiques.

{
  "email": "user@mailinator.com",
  "domain": "mailinator.com",
  "is_disposable": true,
  "is_free": false,
  "provider": "Mailinator"
}

L'adresse IP se situe-t-elle dans une plage bogon ou sur une liste de réputation ?

Les adresses IP Bogon ne doivent jamais atteindre votre serveur depuis l’Internet ouvert ; ils indiquent un en-tête usurpé ou un proxy cassé. Les DNS inversés suspects (noms d'hôte avec « proxy », « tor », « spam ») sont un autre indicateur bon marché. /v1/ip-blocklist/check renvoie un niveau de risque plus une répartition par contrôle.

{
  "ip": "185.220.101.5",
  "is_private": false,
  "is_bogon": false,
  "reverse_dns": "tor-exit-1.example.org",
  "risk_level": "high"
}

Poids et score en une seule fonction

Appelez les trois en parallèle, ajoutez des points pondérés, fixez-les à 100 et choisissez un verdict. Les seuils sont réglables par produit ; commencez par 20 et 70 comme défi et bloquez les coupes.

// signup-score.ts
type Verdict = 'allow' | 'challenge' | 'block';

export async function scoreSignup(input: {
  ip: string;
  email: string;
}): Promise<{ score: number; verdict: Verdict; signals: Record<string, unknown> }> {
  const [vpn, email, blocklist] = await Promise.all([
    fetch('https://api.botoi.com/v1/vpn-detect', postJson({ ip: input.ip })).then(r => r.json()),
    fetch('https://api.botoi.com/v1/disposable-email/check', postJson({ email: input.email })).then(r => r.json()),
    fetch('https://api.botoi.com/v1/ip-blocklist/check', postJson({ ip: input.ip })).then(r => r.json()),
  ]);

  let score = 0;
  if (vpn.is_tor) score += 80;
  else if (vpn.is_datacenter) score += 50;
  else if (vpn.is_vpn) score += 35;

  if (email.is_disposable) score += 60;
  else if (email.is_free) score += 10;

  if (blocklist.risk_level === 'high') score += 40;
  else if (blocklist.risk_level === 'medium') score += 20;

  const verdict: Verdict = score >= 70 ? 'block' : score >= 20 ? 'challenge' : 'allow';
  return { score: Math.min(score, 100), verdict, signals: { vpn, email, blocklist } };
}

function postJson(body: unknown): RequestInit {
  return {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: \`Bearer \${process.env.BOTOI_API_KEY}\`,
    },
    body: JSON.stringify(body),
  };
}

Quelques notes sur les poids. Tor est un signal fort ; 80 points à eux seuls placent la demande dans la bande de blocage. Les adresses IP des centres de données captent une grande partie du trafic des robots, mais également des utilisateurs VPN légitimes en permanence, donc 50 points les mettent en défi, pas en blocage. Les e-mails jetables obtiennent 60 points car les vrais utilisateurs ne choisissent presque jamais Mailinator.

Connectez-le à la route d'inscription

Placez l'appel de score juste avant la création de l'utilisateur. Rejetez la bande de blocage, exigez une vérification par e-mail sur la bande de défi, laissez le reste intact.

// app/api/signup/route.ts (Next.js)
import { NextResponse } from 'next/server';
import { scoreSignup } from '@/lib/signup-score';

export async function POST(req: Request) {
  const body = await req.json();
  const ip = req.headers.get('x-forwarded-for')?.split(',')[0] ?? '0.0.0.0';

  const result = await scoreSignup({ ip, email: body.email });

  if (result.verdict === 'block') {
    await auditLog({ type: 'signup.blocked', ip, email: body.email, score: result.score });
    return NextResponse.json({ error: 'signup_rejected' }, { status: 403 });
  }

  const user = await createUser({
    email: body.email,
    password: body.password,
    requiresEmailVerification: result.verdict === 'challenge',
    riskScore: result.score,
  });

  return NextResponse.json({ user });
}

Auditer chaque décision

Vous ne pouvez pas régler les seuils sans données. Conservez le score et les signaux bruts à chaque inscription.

// Persist the score and signals with the user row for later calibration.
await db.signupAudit.insert({
  userId: user.id,
  ip,
  score: result.score,
  verdict: result.verdict,
  signals: result.signals,
  createdAt: new Date(),
});

Calibrez chaque semaine contre le désabonnement et les abus

Exécutez un rapport une fois par semaine. Un score plus élevé prédit-il un taux de désabonnement, un taux de remboursement ou des rapports d'abus plus élevés ? Si vous obtenez 60 inscriptions à 80 % et 10 inscriptions à 4 %, vos pondérations sont calibrées et vous pouvez resserrer le seuil de blocage. Si le dégradé est plat, repondérez-le.

-- rerun weekly: does the score predict churn and abuse?
SELECT
  FLOOR(score / 10) * 10 AS score_bucket,
  COUNT(*) AS signups,
  ROUND(100.0 * SUM(CASE WHEN churned THEN 1 ELSE 0 END) / COUNT(*), 1) AS churn_pct,
  ROUND(100.0 * SUM(CASE WHEN abuse_reported THEN 1 ELSE 0 END) / COUNT(*), 1) AS abuse_pct
FROM signup_audit
WHERE created_at > NOW() - INTERVAL '90 days'
GROUP BY 1
ORDER BY 1;

Le but est une courbe monotone. Chaque tranche de scores devrait avoir des résultats pires que celui en dessous. Sinon, ajoutez un signal (empreinte digitale de l'appareil, vitesse d'inscription du même /24) ou laissez tomber un poids qui ne tire pas son propre poids.

Où cela correspond-il par rapport au captcha

Approche Friction pour les vrais utilisateurs Coût pour l'attaquant Latence P99
reCAPTCHAv2 3 à 15 % de réduction 1 $ pour 1 000 résolutions 300-800 ms
hCaptcha Entreprise 2 à 8 % de baisse 1 à 2 $ pour 1 000 250-600ms
Score à 3 signaux 0% pour 95% des utilisateurs Doit acquérir une IP propre + une vraie boîte aux lettres 80-120 ms

Un score ne remplace pas le captcha lorsque vous avez besoin de flux de connexion à l'épreuve des robots pour une banque américaine. Il s'agit de la bonne valeur par défaut pour les portes d'inscription, de newsletter et d'essai SaaS.

Ce que cela ne couvre pas

  • Bourrage d'informations d'identification lors de la connexion : utilisez un mot de passe ou une limite de débit par compte.
  • Rafales d'inscription coordonnées à partir de proxys résidentiels : ajoutez des limites de vitesse par /24 et par domaine de messagerie plus minute d'inscription.
  • Utilisateurs qui effectuent la vérification de leur adresse e-mail avec une adresse jetable : définissez un gel de 24 heures sur l'accès aux fonctionnalités pour le groupe de défi.

Obtenez une clé API et déposez-la

Obtenez une clé gratuite sur botoi.com/api/signup. Le niveau gratuit couvre 1 000 scores par jour, suffisamment pour effectuer un calibrage sur une semaine récente d'inscriptions. Les forfaits payants commencent à 9 $/mois pour 10 000 requêtes par jour.

Référence complète pour chaque point final : API de détection VPN, API de vérification des e-mails jetables, et API de vérification de la liste de blocage IP.

FAQ

Pourquoi ne pas utiliser un captcha à la place ?
La conversion des coûts des Captchas (baisse typique : 3 à 15 % des utilisateurs réels) et les fermes commerciales de CAPTCHA résolvent reCAPTCHA v2 pour moins de 1 $ pour mille. La notation avec des signaux évite les frictions pour 95 % des inscriptions et ne conteste que la tranche suspecte.
Quels signaux entrent dans la partition ?
Trois : indicateurs IP VPN/Tor/centre de données, domaine de messagerie jetable ou jetable et accès à la liste de blocage IP (bogons, noms d'hôte suspects). Chacun revient en moins de 50 ms. Pondérez-les pour obtenir un score de risque de 0 à 100, puis décidez par seuil.
Le blocage des adresses IP des centres de données nuit-il aux vrais utilisateurs ?
Les adresses IP d’entreprise et grand public ne correspondent pas aux blocs CIDR du centre de données. Les seuls utilisateurs réels concernés sont les personnes utilisant des VPN permanents, ce qui représente généralement une minorité que vous pouvez acheminer vers un chemin de vérification secondaire plutôt que de bloquer purement et simplement.
Comment gérer le milieu de signal faible ?
Score supérieur à 70 : bloquer. Score inférieur à 20 : autorisé. Entre 20 et 70 : nécessite une vérification de l'e-mail ou une mise à niveau (code SMS, mot de passe). Vous déplacez la friction sur la bande à risque au lieu de tout l’entonnoir.
Puis-je tester la notation par rapport aux inscriptions historiques ?
Oui. Rejouez les 90 derniers jours d'inscription via les trois points de terminaison, rejoignez le score avec les colonnes de désabonnement, de remboursement et de rapport d'abus, et calibrez vos seuils avant d'appliquer quoi que ce soit. Chaque point de terminaison reste stable lors d'appels répétés avec la même entrée.

Commencez a construire avec botoi

150+ endpoints API pour la recherche, le traitement de texte, la generation d'images et les utilitaires pour developpeurs. Offre gratuite, sans carte bancaire.