Aller au contenu

Rejouez le trafic avant de choisir le garde-fou

7 min de lecture

Une attaque au pompage de SMS a vidé notre crédit en quatre-vingt-dix minutes. Les bonnes pratiques publiées donnent une liste de neuf parades, sans dire laquelle mord. En rejouant l'attaque, deux des plus recommandées ne servaient à rien chez nous.

Diagramme à barres : sur les 140 SMS de la fenêtre d'attaque, exiger une adresse e-mail vérifiée en aurait refusé 128, un plafond global de 60 par jour 80, un plafond de 1 par numéro destinataire 73, de 3 par numéro 16, et de 5 par numéro 6.

Si votre produit envoie un code par SMS, quelqu’un peut vous vider votre crédit. Ça s’appelle le pompage de SMS, ou trafic artificiellement gonflé, et le principe est simple. Le fraudeur touche une commission sur la terminaison des messages vers certaines plages de numéros, vous payez votre opérateur, et personne ne lit jamais les codes.

Ce n’est pas exotique. Infobip estime que ce trafic représente de 5 à 40 % du SMS international entre applications selon les régions, pour un coût de 1,6 milliard de dollars sur la seule année 2023.

Nous en avons pris une, sur une application de voyage à vélo. Vingt-huit comptes jetables, 140 SMS vers des numéros monténégrins, quatre-vingt-dix minutes. Le crédit était à sec à la fin, et la vérification par téléphone est restée cassée un jour pour les vrais utilisateurs. Aucune annonce, aucune réservation, aucun message, aucun téléphone réellement vérifié. Les comptes n’étaient pas le but, ils étaient le carburant.

On trouve partout la liste des garde-fous possibles. Le problème est de savoir lesquels installent vraiment quelque chose, et dans quel ordre.

La limite de débit fonctionnait parfaitement

Nous avions une limite, cinq SMS par heure. Elle n’a jamais cédé. Chaque compte a brûlé exactement cinq SMS, puis a été abandonné.

Le compteur était indexé sur l’identifiant du compte. Or créer un compte était gratuit, instantané et illimité. La limite n’a donc pas été forcée, elle a été débordée par le nombre de comptes. Vingt-huit fois cinq, ça fait cent quarante.

D’où la première question à poser à chaque garde-fou que vous envisagez. Qu’est-ce qu’il coûte à l’attaquant de remettre ce compteur à zéro ? Si la réponse est gratuite et instantanée, vous n’avez pas une limite, vous avez un pas de quantification.

Ce que dit l’intuition, ce que dit le rejeu

Les bonnes pratiques publiées ne manquent pas. Twilio en recense neuf, des limites de débit à la restriction des pays de destination, en passant par l’analyse des adresses IP. C’est une liste utile, et ce n’est pas un classement. Les limites de débit y arrivent en quatrième position, avec le numéro destinataire comme une clé parmi quatre, et l’exigence d’une adresse e-mail vérifiée en cinquième, présentée comme de la friction contre les robots.

Rien là-dedans ne dit ce qui vous concerne. J’avais moi-même écrit que la limite par numéro destinataire cassait la boucle et qu’elle était le correctif le plus rentable. Puis j’ai rejoué les 140 envois de l’attaque à travers chaque garde-fou candidat, un par un, pour voir combien chacun aurait refusés.

garde-fou candidat SMS refusés sur 140
exiger une adresse e-mail vérifiée 128
plafond global de 60 par jour 80
plafond de 1 par numéro destinataire 73
plafond de 3 par numéro destinataire 16
plafond de 5 par numéro destinataire 6

Le garde-fou sur lequel je comptais arrête 16 envois sur 140.

La raison tient dans une ligne des journaux. L’attaquant a fait tourner 67 numéros pour 140 envois, soit environ deux par numéro. Il n’a presque jamais retapé le même. Un plafond raisonnable par numéro passe donc à côté de la quasi-totalité du trafic, et pour qu’il morde vraiment il faudrait descendre à un seul SMS par numéro et par jour, ce qui casse le premier utilisateur qui se trompe d’un chiffre.

Ce qui mord, c’est la précondition. Vingt-six des vingt-huit comptes frauduleux n’avaient jamais vérifié leur adresse e-mail. En regardant de plus près, aucun n’a jamais appelé la fonction de vérification du code e-mail, donc la précondition aurait en réalité bloqué la totalité des envois et pas 128.

Et elle ne coûte rien dans le parcours réel, où la vérification de l’adresse vient déjà avant et conditionne déjà la réservation.

Deux parades recommandées qui ne nous servaient à rien

Les deux échouent, et pas pour la même raison.

La restriction des pays de destination aurait arrêté l’attaque entière, tous les envois partant vers un seul indicatif. Elle est inapplicable chez nous. Nos vrais utilisateurs vérifient leur numéro depuis le Cambodge, le Sénégal, l’Inde, l’Argentine ou la Turquie, parce que c’est une application de voyage. Le remède aurait fait plus de dégâts que l’attaque. Ce garde-fou échoue sur le produit, pas sur le trafic.

Le bannissement de l’adresse IP tombe encore ailleurs. Une seule adresse portait 141 des 162 appels, ce qui en fait une cible évidente, sauf qu’elle n’est jamais revenue depuis. Nos fonctions n’ont pas de filtrage natif, il faudrait un répartiteur de charge externe et un pare-feu applicatif devant, soit une trentaine de dollars par mois en permanence, pour fermer une porte que personne n’utilise plus et qu’un changement d’adresse rouvre. Celui-là échoue sur l’économie.

Une liste de bonnes pratiques ne peut pas savoir ça. Elle ne connaît ni votre trafic, ni vos utilisateurs, ni votre facture.

Le garde-fou qui mord est celui qui renchérit l’identité

C’est la leçon transférable, et elle vaut hors du SMS.

Une limite par cible suppose que l’attaquant manque de cibles. Un plafond global suppose qu’il vous laisse le temps de le voir monter. Une précondition sur l’identité, elle, attaque ce qui rend l’attaque possible, à savoir qu’un compte ne coûtait rien.

Rangez donc vos candidats non pas par ce qu’ils bloquent en théorie, mais par ce qu’ils exigent de l’attaquant. Puis vérifiez le classement en rejouant votre propre trafic, le vrai comme le frauduleux, parce que le même rejeu vous donne aussi le seuil. Notre plafond global est à 60 par jour, choisi contre une distribution réelle de 6 en médiane, 12 au neuvième décile et 21 au pic. Un seuil sorti de l’intuition aurait été soit inutile, soit dans les pattes des utilisateurs.

Un garde-fou doit survivre à son propre déclenchement

Trois découvertes en revue, toutes du même genre. Le garde-fou marchait, et son déclenchement cassait autre chose.

Le refus au plafond global levait un code d’erreur que notre enveloppe Sentry considère comme un défaut réel. Chaque appel refusé produisait donc un événement et retenait une instance deux secondes pour le vidage, sur une fonction plafonnée à dix instances. Le garde-fou censé contenir une attaque aurait noyé Sentry pendant qu’elle avait lieu.

Le plafond par numéro valait autant que la limite horaire par compte, cinq. Un utilisateur dépensant son quota horaire fermait donc ce numéro pour vingt-quatre heures, le sien ou celui d’un inconnu. Il est monté à dix, strictement au-dessus de cinq, et cet ordre est devenu la raison d’être de la valeur.

Enfin, la précondition d’e-mail était derrière un drapeau présenté comme désarmable sans déploiement. C’était faux, le fichier d’environnement part dans le paquet déployé. En incident, le chemin rapide est de poser la variable sur le service lui-même, qui gagne parce que le chargeur de fichier ne surcharge pas une variable déjà présente. Un drapeau d’urgence dont on n’a jamais vérifié le chemin de désarmement n’est pas un drapeau d’urgence.

Deux détails qui ne se voient qu’une fois dedans

Notre opérateur facture à l’acceptation du travail, pas à la livraison. Sur les 140 envois, 125 ont été acceptés et débités, y compris vers des numéros qui ne recevraient jamais rien. Vérifiez ce point dans votre contrat avant de compter sur un taux de livraison pour borner la dépense.

Et un compteur par numéro destinataire est un annuaire. Le nôtre garde un dérivé de tous les numéros tentés, donc il lui faut une politique d’expiration, sans quoi le garde-fou crée le problème de données que le hachage était censé éviter.

Ce qu’il y a à regarder chez vous

Prenez votre point d’envoi de SMS et posez-lui trois questions. Sur quoi le compteur est-il indexé, et que coûte-t-il d’en obtenir un neuf. Existe-t-il un plafond que rien n’exempte, et à quelle distance de votre pic réel. Que se passe-t-il dans vos alertes, vos journaux et votre interface le jour où ces garde-fous se déclenchent tous ensemble.

Et si vous avez déjà été touché, gardez les journaux de la fenêtre d’attaque. C’est le seul jeu de données qui vous dira lequel de vos correctifs sert à quelque chose.

Clément Levasseur

© 2026 Clément Levasseur. Tous droits réservés.

LinkedInGitHubEmail