Un Plan anti-spam
Vous aimez construire des choses ? Essayez Hacker News.
Août 2002
(Cet article décrit les techniques de filtrage anti-spam utilisées dans le lecteur de courrier web résistant au spam que nous avons construit pour exercer Arc. Un algorithme amélioré est décrit dans Filtrage Bayésien Amélioré.)
Je pense qu'il est possible d'arrêter le spam, et que les filtres basés sur le contenu sont la voie à suivre. Le talon d'Achille des spammeurs est leur message. Ils peuvent contourner toute autre barrière que vous mettez en place. Ils l'ont fait jusqu'à présent, du moins. Mais ils doivent délivrer leur message, quel qu'il soit. Si nous pouvons écrire un logiciel qui reconnaît leurs messages, il n'y a aucun moyen pour eux de s'en sortir.
Pour le destinataire, le spam est facilement reconnaissable. Si vous engagiez quelqu'un pour lire votre courrier et jeter le spam, il aurait peu de mal à le faire. Jusqu'où devons-nous aller, en deçà de l'IA, pour automatiser ce processus ?
Je pense que nous pourrons résoudre le problème avec des algorithmes assez simples. En fait, j'ai découvert que l'on peut filtrer le spam actuel de manière acceptable en utilisant rien de plus qu'une combinaison bayésienne des probabilités de spam des mots individuels. En utilisant un filtre bayésien légèrement ajusté (comme décrit ci-dessous), nous manquons maintenant moins de 5 spams sur 1000, avec 0 faux positifs.
L'approche statistique n'est généralement pas la première que les gens essaient lorsqu'ils écrivent des filtres anti-spam. Le premier instinct de la plupart des hackers est d'essayer d'écrire un logiciel qui reconnaît les propriétés individuelles du spam. Vous regardez les spams et vous pensez, quel culot ces gars d'essayer de m'envoyer un mail qui commence par "Cher ami" ou dont la ligne d'objet est entièrement en majuscules et se termine par huit points d'exclamation. Je peux filtrer ce genre de choses avec environ une ligne de code.
Et c'est ce que vous faites, et au début ça marche. Quelques règles simples réduiront considérablement votre spam entrant. Le simple fait de chercher le mot "clic" interceptera 79,7 % des e-mails de mon corpus de spam, avec seulement 1,2 % de faux positifs.
J'ai passé environ six mois à écrire un logiciel qui recherchait des caractéristiques individuelles du spam avant d'essayer l'approche statistique. Ce que j'ai découvert, c'est que reconnaître les derniers pourcentages de spams devenait très difficile, et qu'à mesure que je rendais les filtres plus stricts, j'obtenais plus de faux positifs.
Les faux positifs sont des e-mails innocents qui sont identifiés par erreur comme des spams. Pour la plupart des utilisateurs, manquer un e-mail légitime est un ordre de grandeur pire que de recevoir du spam, donc un filtre qui produit des faux positifs est comme un remède contre l'acné qui comporte un risque de mort pour le patient.
Plus un utilisateur reçoit de spam, moins il est susceptible de remarquer un e-mail innocent dans son dossier de spam. Et curieusement, plus vos filtres anti-spam sont efficaces, plus les faux positifs deviennent dangereux, car lorsque les filtres sont vraiment bons, les utilisateurs seront plus enclins à ignorer tout ce qu'ils interceptent.
Je ne sais pas pourquoi j'ai évité d'essayer l'approche statistique pendant si longtemps. Je pense que c'était parce que je suis devenu accro à l'idée d'identifier moi-même les caractéristiques du spam, comme si je jouais à une sorte de jeu de compétition avec les spammeurs. (Les non-hackers ne le réalisent pas souvent, mais la plupart des hackers sont très compétitifs.) Lorsque j'ai essayé l'analyse statistique, j'ai immédiatement constaté qu'elle était bien plus astucieuse que moi. Elle a découvert, bien sûr, que des termes comme "virtumundo" et "teens" étaient de bons indicateurs de spam. Mais elle a aussi découvert que "per" et "FL" et "ff0000" sont de bons indicateurs de spam. En fait, "ff0000" (HTML pour rouge vif) s'avère être un indicateur de spam aussi bon que n'importe quel terme pornographique.
Voici un aperçu de la façon dont je fais le filtrage statistique. Je commence avec un corpus de spam et un de courrier non-spam. Actuellement, chacun contient environ 4000 messages. Je scanne l'intégralité du texte, y compris les en-têtes et le HTML et JavaScript intégrés, de chaque message dans chaque corpus. Je considère actuellement les caractères alphanumériques, les tirets, les apostrophes et les signes dollar comme faisant partie des jetons (tokens), et tout le reste comme un séparateur de jetons. (Il y a probablement place à amélioration ici.) J'ignore les jetons qui sont entièrement numériques, et j'ignore également les commentaires HTML, ne les considérant même pas comme des séparateurs de jetons.
Je compte le nombre de fois que chaque jeton (en ignorant la casse, actuellement) apparaît dans chaque corpus. À ce stade, j'obtiens deux grandes tables de hachage, une pour chaque corpus, mappant les jetons au nombre d'occurrences.
Ensuite, je crée une troisième table de hachage, cette fois-ci mappant chaque jeton à la probabilité qu'un e-mail le contenant soit un spam, que je calcule comme suit [1] : (let ((g (* 2 (or (gethash word good) 0))) (b (or (gethash word bad) 0))) (unless (< (+ g b) 5) (max .01 (min .99 (float (/ (min 1 (/ b nbad)) (+ (min 1 (/ g ngood)) (min 1 (/ b nbad))))))))) où word
est le jeton dont nous calculons la probabilité, good
et bad
sont les tables de hachage que j'ai créées à la première étape, et ngood
et nbad
sont respectivement le nombre de messages non-spam et de spam.
J'ai expliqué cela sous forme de code pour montrer quelques détails importants. Je veux légèrement biaiser les probabilités pour éviter les faux positifs, et par essais et erreurs, j'ai trouvé qu'une bonne façon de le faire est de doubler tous les nombres dans good
. Cela aide à distinguer entre les mots qui apparaissent occasionnellement dans les e-mails légitimes et ceux qui n'apparaissent presque jamais. Je ne considère que les mots qui apparaissent plus de cinq fois au total (en fait, à cause du doublement, apparaître trois fois dans le courrier non-spam serait suffisant). Et puis il y a la question de la probabilité à attribuer aux mots qui apparaissent dans un corpus mais pas dans l'autre. Encore une fois par essais et erreurs, j'ai choisi .01 et .99. Il peut y avoir de la place pour des ajustements ici, mais à mesure que le corpus grandira, de tels ajustements se produiront automatiquement de toute façon.
Les plus observateurs remarqueront que si je considère chaque corpus comme un seul long flux de texte pour le comptage des occurrences, j'utilise le nombre d'e-mails dans chacun, plutôt que leur longueur combinée, comme diviseur dans le calcul des probabilités de spam. Cela ajoute un autre léger biais pour se protéger contre les faux positifs.
Lorsqu'un nouveau courrier arrive, il est scanné en jetons, et les quinze jetons les plus intéressants, où l'intérêt est mesuré par l'éloignement de leur probabilité de spam par rapport à un .5 neutre, sont utilisés pour calculer la probabilité que le courrier soit un spam. Si probs
est une liste des quinze probabilités individuelles, vous calculez la probabilité combinée ainsi : (let ((prod (apply #'* probs))) (/ prod (+ prod (apply #'* (mapcar #'(lambda (x) (- 1 x)) probs))))) Une question qui se pose en pratique est quelle probabilité attribuer à un mot que vous n'avez jamais vu, c'est-à-dire un mot qui n'apparaît pas dans la table de hachage des probabilités de mots. J'ai trouvé, encore une fois par essais et erreurs, que .4 est un bon nombre à utiliser. Si vous n'avez jamais vu un mot auparavant, il est probablement assez innocent ; les mots de spam ont tendance à être trop familiers.
Il y a des exemples de cet algorithme appliqué à de vrais e-mails dans une annexe à la fin.
Je considère un courrier comme du spam si l'algorithme ci-dessus lui attribue une probabilité de plus de .9 d'être du spam. Mais en pratique, peu importe où je place ce seuil, car peu de probabilités se retrouvent au milieu de la plage.
Un grand avantage de l'approche statistique est que vous n'avez pas à lire autant de spams. Au cours des six derniers mois, j'ai lu littéralement des milliers de spams, et c'est vraiment démoralisant. Norbert Wiener a dit que si vous rivalisez avec des esclaves, vous devenez un esclave, et il y a quelque chose de tout aussi dégradant à rivaliser avec les spammeurs. Pour reconnaître les caractéristiques individuelles du spam, il faut essayer de se mettre dans l'esprit du spammeur, et franchement, je veux passer le moins de temps possible dans l'esprit des spammeurs.
Mais le véritable avantage de l'approche bayésienne, bien sûr, est que vous savez ce que vous mesurez. Les filtres reconnaissant les caractéristiques, comme SpamAssassin, attribuent un "score" de spam à l'e-mail. L'approche bayésienne attribue une probabilité réelle. Le problème avec un "score" est que personne ne sait ce que cela signifie. L'utilisateur ne sait pas ce que cela signifie, mais pire encore, le développeur du filtre non plus. Combien de points un e-mail devrait-il obtenir pour contenir le mot "sexe" ? Une probabilité peut bien sûr être erronée, mais il y a peu d'ambiguïté quant à sa signification, ou à la manière dont les preuves doivent être combinées pour la calculer. D'après mon corpus, "sexe" indique une probabilité de .97 que l'e-mail contenant soit un spam, tandis que "sexy" indique une probabilité de .99. Et la règle de Bayes, tout aussi univoque, dit qu'un e-mail contenant les deux mots aurait, en l'absence (improbable) de toute autre preuve, 99,97 % de chances d'être un spam.
Parce qu'elle mesure des probabilités, l'approche bayésienne prend en compte toutes les preuves dans l'e-mail, bonnes et mauvaises. Les mots qui apparaissent de manière disproportionnée rarement dans le spam (comme "cependant", "ce soir" ou "apparemment") contribuent autant à diminuer la probabilité que les mauvais mots comme "se désabonner" et "opt-in" à l'augmenter. Ainsi, un e-mail par ailleurs innocent qui se trouve à inclure le mot "sexe" ne sera pas marqué comme spam.
Idéalement, bien sûr, les probabilités devraient être calculées individuellement pour chaque utilisateur. Je reçois beaucoup d'e-mails contenant le mot "Lisp", et (jusqu'à présent) aucun spam ne le contient. Un mot comme celui-là est donc en fait une sorte de mot de passe pour m'envoyer du courrier. Dans mon logiciel de filtrage anti-spam précédent, l'utilisateur pouvait configurer une liste de tels mots et les courriers les contenant passaient automatiquement les filtres. Sur ma liste, j'ai mis des mots comme "Lisp" et aussi mon code postal, afin que les reçus de commandes en ligne (qui sonnent autrement plutôt comme du spam) passent. Je pensais être très malin, mais j'ai constaté que le filtre bayésien faisait la même chose pour moi, et découvrait en outre beaucoup de mots auxquels je n'avais pas pensé.
Quand j'ai dit au début que nos filtres laissaient passer moins de 5 spams sur 1000 avec 0 faux positifs, je parle du filtrage de mon courrier basé sur un corpus de mon courrier. Mais ces chiffres ne sont pas trompeurs, car c'est l'approche que je préconise : filtrer le courrier de chaque utilisateur en fonction du spam et du courrier non-spam qu'il reçoit. Essentiellement, chaque utilisateur devrait avoir deux boutons de suppression, suppression ordinaire et suppression-comme-spam. Tout ce qui est supprimé comme spam va dans le corpus de spam, et tout le reste va dans le corpus non-spam.
Vous pourriez commencer les utilisateurs avec un filtre initial (seed filter), mais finalement chaque utilisateur devrait avoir ses propres probabilités par mot basées sur le courrier réel qu'il reçoit. Cela (a) rend les filtres plus efficaces, (b) permet à chaque utilisateur de décider de sa propre définition précise du spam, et (c) peut-être le meilleur de tout, rend difficile pour les spammeurs d'ajuster les courriers pour passer les filtres. Si une grande partie du "cerveau" du filtre se trouve dans les bases de données individuelles, alors le simple fait d'ajuster les spams pour passer les filtres initiaux ne garantira rien quant à leur capacité à passer les filtres variés et beaucoup plus entraînés des utilisateurs individuels.
Le filtrage anti-spam basé sur le contenu est souvent combiné avec une liste blanche (whitelist), une liste d'expéditeurs dont le courrier peut être accepté sans filtrage. Une façon simple de construire une telle liste blanche est de conserver une liste de chaque adresse à laquelle l'utilisateur a déjà envoyé du courrier. Si un lecteur de courrier a un bouton "supprimer-comme-spam", vous pourriez également ajouter l'adresse de l'expéditeur de chaque e-mail que l'utilisateur a supprimé comme un courrier indésirable ordinaire.
Je suis un défenseur des listes blanches, mais plus comme un moyen d'économiser des calculs que comme un moyen d'améliorer le filtrage. Je pensais que les listes blanches faciliteraient le filtrage, car vous n'auriez qu'à filtrer les e-mails de personnes dont vous n'avez jamais entendu parler, et quelqu'un qui vous envoie un e-mail pour la première fois est contraint par la convention dans ce qu'il peut vous dire. Quelqu'un que vous connaissez déjà pourrait vous envoyer un e-mail parlant de sexe, mais quelqu'un qui vous envoie un e-mail pour la première fois ne le ferait probablement pas. Le problème est que les gens peuvent avoir plus d'une adresse e-mail, donc une nouvelle adresse d'expéditeur ne garantit pas que l'expéditeur vous écrit pour la première fois. Il n'est pas rare qu'un vieil ami (surtout s'il est un hacker) vous envoie soudainement un e-mail avec une nouvelle adresse d'expéditeur, vous ne pouvez donc pas risquer de faux positifs en filtrant le courrier provenant d'adresses inconnues de manière particulièrement stricte.
Dans un sens, cependant, mes filtres incarnent eux-mêmes une sorte de liste blanche (et de liste noire) car ils sont basés sur des messages entiers, y compris les en-têtes. Dans cette mesure, ils "connaissent" les adresses e-mail des expéditeurs de confiance et même les routes par lesquelles le courrier leur parvient. Et ils savent la même chose sur le spam, y compris les noms de serveurs, les versions de mailer et les protocoles.
Si je pensais pouvoir maintenir les taux actuels de filtrage anti-spam, je considérerais ce problème comme résolu. Mais cela ne signifie pas grand-chose de pouvoir filtrer la plupart du spam actuel, car le spam évolue. En effet, la plupart des techniques anti-spam jusqu'à présent ont été comme des pesticides qui ne font rien de plus que créer une nouvelle souche de bugs résistante.
J'ai plus d'espoir concernant les filtres bayésiens, car ils évoluent avec le spam. Ainsi, lorsque les spammeurs commencent à utiliser "c0ck" au lieu de "cock" pour échapper aux filtres anti-spam simplistes basés sur des mots individuels, les filtres bayésiens le remarquent automatiquement. En effet, "c0ck" est une preuve bien plus accablante que "cock", et les filtres bayésiens savent précisément à quel point.
Pourtant, quiconque propose un plan de filtrage anti-spam doit être capable de répondre à la question : si les spammeurs savaient exactement ce que vous faisiez, à quel point pourraient-ils vous contourner ? Par exemple, je pense que si le filtrage anti-spam basé sur les sommes de contrôle (checksums) devient un obstacle sérieux, les spammeurs passeront simplement aux techniques de type "mad-lib" pour générer les corps de message.
Pour battre les filtres bayésiens, il ne suffirait pas aux spammeurs de rendre leurs e-mails uniques ou d'arrêter d'utiliser des mots "coquins" individuels. Ils devraient rendre leurs courriers indiscernables de votre courrier ordinaire. Et cela, je pense, les contraindrait sévèrement. Le spam est principalement constitué de propositions commerciales, donc à moins que votre courrier habituel ne soit entièrement composé de propositions commerciales, les spams auront inévitablement un caractère différent. Et les spammeurs devraient aussi, bien sûr, changer (et continuer à changer) toute leur infrastructure, car sinon les en-têtes paraîtraient toujours aussi mauvais aux filtres bayésiens, quoi qu'ils fassent au corps du message. Je n'en sais pas assez sur l'infrastructure que les spammeurs utilisent pour savoir à quel point il serait difficile de rendre les en-têtes innocents, mais je suppose que ce serait encore plus difficile que de rendre le message innocent.
En supposant qu'ils puissent résoudre le problème des en-têtes, le spam du futur ressemblera probablement à ceci : Hey there. Thought you should check out the following: http://www.27meg.com/foo car c'est à peu près la seule proposition commerciale que le filtrage basé sur le contenu laissera au spammeur. (En effet, il sera difficile même de faire passer cela par les filtres, car si tout le reste dans l'e-mail est neutre, la probabilité de spam dépendra de l'URL, et il faudra un certain effort pour la rendre neutre.)
Les spammeurs vont des entreprises gérant des listes dites "opt-in" qui n'essaient même pas de dissimuler leur identité, aux individus qui détournent des serveurs de messagerie pour envoyer des spams faisant la promotion de sites pornographiques. Si nous utilisons le filtrage pour réduire leurs options à des courriers comme celui ci-dessus, cela devrait à peu près mettre hors d'affaires les spammeurs situés à l'extrémité "légitime" du spectre ; ils se sentent obligés par diverses lois d'État d'inclure des clauses standard sur la raison pour laquelle leur spam n'est pas du spam, et comment annuler votre "abonnement", et ce genre de texte est facile à reconnaître.
(Je pensais autrefois qu'il était naïf de croire que des lois plus strictes diminueraient le spam. Maintenant, je pense que si des lois plus strictes ne diminuent peut-être pas la quantité de spam que les spammeurs envoient, elles peuvent certainement aider les filtres à diminuer la quantité de spam que les destinataires voient réellement.)
Sur tout le spectre, si vous restreignez les propositions commerciales que les spammeurs peuvent faire, vous aurez inévitablement tendance à les mettre hors d'affaires. Ce mot affaires est important à retenir. Les spammeurs sont des hommes d'affaires. Ils envoient du spam parce que ça marche. Ça marche parce que bien que le taux de réponse soit abominablement bas (au mieux 15 pour un million, contre 3000 pour un million pour un envoi de catalogue), le coût, pour eux, est pratiquement nul. Le coût est énorme pour les destinataires, environ 5 semaines-homme pour chaque million de destinataires qui passent une seconde à supprimer le spam, mais le spammeur n'a pas à payer cela.
L'envoi de spam coûte cependant quelque chose au spammeur. [2] Ainsi, plus nous pouvons réduire le taux de réponse – que ce soit par le filtrage, ou en utilisant des filtres pour forcer les spammeurs à diluer leurs propositions – moins d'entreprises trouveront intéressant d'envoyer du spam.
La raison pour laquelle les spammeurs utilisent les types de propositions commerciales qu'ils font est d'augmenter les taux de réponse. C'est peut-être encore plus dégoûtant que de se mettre dans l'esprit d'un spammeur, mais jetons un coup d'œil rapide à l'esprit de quelqu'un qui répond à un spam. Cette personne est soit étonnamment crédule, soit profondément dans le déni de ses intérêts sexuels. Dans les deux cas, aussi répugnant ou idiot que le spam nous paraisse, il est excitant pour eux. Les spammeurs ne diraient pas ces choses si elles ne semblaient pas excitantes. Et "je pensais que tu devrais jeter un œil à ce qui suit" n'aura tout simplement pas le même attrait pour le destinataire du spam que les types de choses que les spammeurs disent maintenant. Résultat : s'il ne peut pas contenir de propositions commerciales excitantes, le spam devient moins efficace en tant que véhicule marketing, et moins d'entreprises veulent l'utiliser.
C'est la grande victoire au final. J'ai commencé à écrire un logiciel de filtrage anti-spam parce que je ne voulais plus avoir à regarder ces choses. Mais si nous devenons assez bons pour filtrer le spam, cela cessera de fonctionner, et les spammeurs arrêteront réellement de l'envoyer.
De toutes les approches pour lutter contre le spam, des logiciels aux lois, je crois que le filtrage bayésien sera le plus efficace. Mais je pense aussi que plus nous entreprenons de types d'efforts anti-spam différents, mieux c'est, car toute mesure qui contraint les spammeurs aura tendance à faciliter le filtrage. Et même dans le monde du filtrage basé sur le contenu, je pense que ce sera une bonne chose s'il y a de nombreux types de logiciels différents utilisés simultanément. Plus il y a de filtres différents, plus il sera difficile pour les spammeurs d'ajuster les spams pour les traverser.
Annexe : Exemples de Filtrage
Voici un exemple de spam arrivé pendant que j'écrivais cet article. Les quinze mots les plus intéressants de ce spam sont : qvp0045 indira mx-05 intimail $7500 freeyankeedom cdo bluefoxmedia jpg unsecured platinum 3d0 qves 7c5 7c266675 Les mots sont un mélange d'éléments provenant des en-têtes et du corps du message, ce qui est typique du spam. Il est également typique du spam que chacun de ces mots ait une probabilité de spam, dans ma base de données, de .99. En fait, il y a plus de quinze mots avec des probabilités de .99, et ce ne sont que les quinze premiers rencontrés.
Malheureusement, cela fait de cet e-mail un exemple ennuyeux de l'utilisation de la règle de Bayes. Pour voir une variété intéressante de probabilités, nous devons regarder ce spam en fait assez atypique.
Les quinze mots les plus intéressants de ce spam, avec leurs probabilités, sont : madam 0.99 promotion 0.99 republic 0.99 shortest 0.047225013 mandatory 0.047225013 standardization 0.07347802 sorry 0.08221981 supported 0.09019077 people's 0.09019077 enter 0.9075001 quality 0.8921298 organization 0.12454646 investment 0.8568143 very 0.14758544 valuable 0.82347786 Cette fois, les preuves sont un mélange de bonnes et de mauvaises. Un mot comme "shortest" (le plus court) est presque autant une preuve d'innocence qu'un mot comme "madam" ou "promotion" est une preuve de culpabilité. Mais le cas de culpabilité est toujours plus fort. Si vous combinez ces nombres selon la règle de Bayes, la probabilité résultante est de .9027.
"Madam" vient évidemment des spams commençant par "Cher Monsieur ou Madame". Ils ne sont pas très courants, mais le mot "madam" n'apparaît jamais dans mes e-mails légitimes, et tout est une question de ratio.
"Republic" obtient un score élevé car il apparaît souvent dans les e-mails d'arnaque nigériane, et aussi une ou deux fois dans les spams faisant référence à la Corée et à l'Afrique du Sud. On pourrait dire que c'est un accident qu'il aide ainsi à identifier ce spam. Mais j'ai constaté en examinant les probabilités de spam qu'il y a beaucoup de ces accidents, et ils ont une étrange tendance à pousser les choses dans la bonne direction plutôt que la mauvaise. Dans ce cas, ce n'est pas entièrement une coïncidence que le mot "Republic" apparaisse dans les e-mails d'arnaque nigériane et ce spam. Il existe toute une catégorie de propositions commerciales douteuses impliquant des pays moins développés, et ceux-ci sont à leur tour plus susceptibles d'avoir des noms qui spécifient explicitement (parce qu'ils ne le sont pas) qu'ils sont des républiques.[3]
D'autre part, "enter" est une véritable erreur. Il apparaît principalement dans les instructions de désabonnement, mais ici il est utilisé de manière complètement innocente. Heureusement, l'approche statistique est assez robuste et peut tolérer un grand nombre d'erreurs avant que les résultats ne commencent à être faussés.
À titre de comparaison, voici un exemple de cet oiseau rare, un spam qui passe les filtres. Pourquoi ? Parce que par pur hasard, il se trouve qu'il est rempli de mots qui apparaissent dans mon courrier réel : perl 0.01 python 0.01 tcl 0.01 scripting 0.01 morris 0.01 graham 0.01491078 guarantee 0.9762507 cgi 0.9734398 paul 0.027040077 quite 0.030676773 pop3 0.042199217 various 0.06080265 prices 0.9359873 managed 0.06451222 difficult 0.071706355 Il y a quelques bonnes nouvelles ici. Premièrement, ce courrier ne passerait probablement pas les filtres de quelqu'un qui ne se spécialiserait pas dans les langages de programmation et n'aurait pas un bon ami nommé Morris. Pour l'utilisateur moyen, les cinq premiers mots ici seraient neutres et ne contribueraient pas à la probabilité de spam.
Deuxièmement, je pense que le filtrage basé sur les paires de mots (voir ci-dessous) pourrait bien l'intercepter : "cost effective" (rentable), "setup fee" (frais d'installation), "money back" (remboursement) – des éléments plutôt incriminants. Et bien sûr, s'ils continuaient à me spammer (ou un réseau dont je faisais partie), "Hostex" lui-même serait reconnu comme un terme de spam.
Enfin, voici un e-mail innocent. Ses quinze mots les plus intéressants sont les suivants : continuation 0.01 describe 0.01 continuations 0.01 example 0.033600237 programming 0.05214485 i'm 0.055427782 examples 0.07972858 color 0.9189189 localhost 0.09883721 hi 0.116539136 california 0.84421706 same 0.15981844 spot 0.1654587 us-ascii 0.16804294 what 0.19212411 La plupart des mots ici indiquent que le courrier est innocent. Il y a deux mots "malodorants", "color" (les spammeurs adorent les polices colorées) et "California" (qui apparaît dans les témoignages et aussi dans les menus de formulaires), mais ils ne sont pas suffisants pour l'emporter sur des mots évidemment innocents comme "continuation" et "example".
Il est intéressant de noter que "describe" est classé comme si complètement innocent. Il n'est apparu dans aucun de mes 4000 spams. Les données s'avèrent pleines de telles surprises. L'une des choses que l'on apprend en analysant les textes de spam est à quel point le sous-ensemble de la langue dans lequel les spammeurs opèrent est étroit. C'est ce fait, combiné au vocabulaire tout aussi caractéristique du courrier de chaque utilisateur individuel, qui fait du filtrage bayésien un bon pari.
Annexe : Plus d'Idées
Une idée que je n'ai pas encore essayée est de filtrer en se basant sur des paires de mots, ou même des triplets, plutôt que sur des mots individuels. Cela devrait donner une estimation beaucoup plus précise de la probabilité. Par exemple, dans ma base de données actuelle, le mot "offers" (offres) a une probabilité de .96. Si vous basiez les probabilités sur des paires de mots, vous obtiendriez "special offers" (offres spéciales) et "valuable offers" (offres précieuses) avec des probabilités de .99 et, disons, "approach offers" (comme dans "cette approche offre") avec une probabilité de .1 ou moins.
La raison pour laquelle je n'ai pas fait cela est que le filtrage basé sur des mots individuels fonctionne déjà si bien. Mais cela signifie qu'il y a de la marge pour resserrer les filtres si le spam devient plus difficile à détecter. (Curieusement, un filtre basé sur des paires de mots serait en fait un générateur de texte à chaîne de Markov fonctionnant à l'envers.)
Les caractéristiques spécifiques du spam (par exemple, ne pas voir l'adresse du destinataire dans le champ "À :") ont bien sûr une valeur pour reconnaître le spam. Elles peuvent être prises en compte dans cet algorithme en les traitant comme des mots virtuels. Je le ferai probablement dans les futures versions, du moins pour une poignée des indicateurs de spam les plus flagrants. Les filtres anti-spam reconnaissant les caractéristiques sont corrects dans de nombreux détails ; ce qui leur manque, c'est une discipline globale pour combiner les preuves.
Reconnaître les caractéristiques non-spam peut être plus important que reconnaître les caractéristiques de spam. Les faux positifs sont une telle préoccupation qu'ils exigent des mesures extraordinaires. Je vais probablement dans les futures versions ajouter un deuxième niveau de test conçu spécifiquement pour éviter les faux positifs. Si un courrier déclenche ce deuxième niveau de filtres, il sera accepté même si sa probabilité de spam est supérieure au seuil.
Je ne m'attends pas à ce que ce deuxième niveau de filtrage soit bayésien. Il sera inévitablement non seulement ad hoc, mais basé sur des suppositions, car le nombre de faux positifs n'aura pas tendance à être suffisamment important pour que des schémas soient remarqués. (C'est tout aussi bien, de toute façon, si un système de sauvegarde ne repose pas sur la même technologie que le système principal.)
Une autre chose que je pourrais essayer à l'avenir est de porter une attention particulière à des parties spécifiques de l'e-mail. Par exemple, environ 95 % du spam actuel inclut l'URL d'un site qu'ils veulent que vous visitiez. (Les 5 % restants veulent que vous appeliez un numéro de téléphone, répondiez par e-mail ou à une adresse postale américaine, ou dans quelques cas, que vous achetiez une certaine action.) L'URL est dans de tels cas pratiquement suffisante à elle seule pour déterminer si l'e-mail est un spam.
Les noms de domaine diffèrent du reste du texte dans un e-mail (non-allemand) en ce qu'ils sont souvent constitués de plusieurs mots collés ensemble. Bien que coûteux en termes de calcul dans le cas général, il pourrait être intéressant d'essayer de les décomposer. Si un filtre n'a jamais vu le jeton "xxxporn" auparavant, il aura une probabilité de spam individuelle de .4, tandis que "xxx" et "porn" ont individuellement des probabilités (dans mon corpus) de .9889 et .99 respectivement, et une probabilité combinée de .9998.
Je m'attends à ce que la décomposition des noms de domaine devienne plus importante à mesure que les spammeurs seront progressivement contraints d'arrêter d'utiliser des mots incriminants dans le texte de leurs messages. (Une URL avec une adresse IP est bien sûr un signe extrêmement incriminant, sauf dans le courrier de quelques administrateurs système.)
Il pourrait être une bonne idée d'avoir une liste d'URL promues par les spammeurs, maintenue de manière collaborative. Nous aurions besoin d'une métrique de confiance du type étudié par Raph Levien pour prévenir les soumissions malveillantes ou incompétentes, mais si nous avions une telle chose, cela donnerait un coup de pouce à tout logiciel de filtrage. Ce serait aussi une base pratique pour les boycotts.
Une autre façon de tester les URL douteuses serait d'envoyer un robot d'exploration (crawler) pour examiner le site avant que l'utilisateur ne regarde l'e-mail le mentionnant. Vous pourriez utiliser un filtre bayésien pour évaluer le site comme vous le feriez pour un e-mail, et tout ce qui serait trouvé sur le site pourrait être inclus dans le calcul de la probabilité que l'e-mail soit un spam. Une URL qui mènerait à une redirection serait bien sûr particulièrement suspecte.
Un projet coopératif qui, je pense, serait vraiment une bonne idée serait d'accumuler un corpus géant de spam. Un corpus large et propre est la clé pour que le filtrage bayésien fonctionne bien. Les filtres bayésiens pourraient en fait utiliser le corpus comme entrée. Mais un tel corpus serait également utile pour d'autres types de filtres, car il pourrait être utilisé pour les tester.
La création d'un tel corpus pose quelques problèmes techniques. Nous aurions besoin de métriques de confiance pour prévenir les soumissions malveillantes ou incompétentes, bien sûr. Nous aurions également besoin de moyens d'effacer les informations personnelles (pas seulement les adresses "À :" et "Cc :", mais aussi par exemple les arguments des URL de désabonnement, qui encodent souvent l'adresse "À :") des courriers dans le corpus. Si quelqu'un veut se charger de ce projet, ce serait une bonne chose pour le monde.
Annexe : Définir le Spam
Je pense qu'il existe un consensus approximatif sur ce qu'est le spam, mais il serait utile d'avoir une définition explicite. Nous devrons le faire si nous voulons établir un corpus central de spam, ou même comparer les taux de filtrage de spam de manière significative.
Pour commencer, le spam n'est pas un e-mail commercial non sollicité. Si quelqu'un de mon quartier apprenait que je cherchais un vieux Raleigh trois vitesses en bon état, et m'envoyait un e-mail pour m'en proposer un, je serais ravi, et pourtant cet e-mail serait à la fois commercial et non sollicité. La caractéristique définissante du spam (en fait, sa raison d'être) n'est pas qu'il soit non sollicité, mais qu'il soit automatisé.
Il est également purement accessoire que le spam soit généralement commercial. Si quelqu'un commençait à envoyer des e-mails de masse pour soutenir une cause politique, par exemple, ce serait tout autant du spam qu'un e-mail faisant la promotion d'un site pornographique.
Je propose de définir le spam comme un e-mail automatisé non sollicité. Cette définition inclut donc certains e-mails que de nombreuses définitions légales du spam n'incluent pas. Les définitions légales du spam, influencées vraisemblablement par les lobbyistes, ont tendance à exclure le courrier envoyé par des entreprises ayant une "relation existante" avec le destinataire. Mais acheter quelque chose à une entreprise, par exemple, n'implique pas que vous ayez sollicité des e-mails continus de leur part. Si je commande quelque chose dans une boutique en ligne, et qu'ils m'envoient ensuite un flux de spam, c'est toujours du spam.
Les entreprises qui envoient du spam vous offrent souvent un moyen de vous "désabonner", ou vous demandent d'aller sur leur site et de modifier vos "préférences de compte" si vous voulez arrêter de recevoir du spam. Ce n'est pas suffisant pour que le courrier cesse d'être du spam. Ne pas se désinscrire n'est pas la même chose que s'inscrire. À moins que le destinataire n'ait explicitement coché une case clairement étiquetée (dont la valeur par défaut était "non") demandant à recevoir l'e-mail, alors c'est du spam.
Dans certaines relations commerciales, vous sollicitez implicitement certains types de courrier. Lorsque vous commandez en ligne, je pense que vous sollicitez implicitement un reçu et une notification lorsque la commande est expédiée. Cela ne me dérange pas lorsque Verisign m'envoie un courrier m'avertissant qu'un nom de domaine est sur le point d'expirer (du moins, s'ils en sont le registraire réel). Mais lorsque Verisign m'envoie un e-mail offrant un Guide GRATUIT pour Construire Mon Site Web E-Commerce, c'est du spam.
Notes :
[1] Les exemples de cet article sont traduits en Common Lisp pour, croyez-le ou non, une plus grande accessibilité. L'application décrite ici est une que nous avons écrite afin de tester un nouveau dialecte Lisp appelé Arc qui n'est pas encore sorti.
[2] Actuellement, le taux le plus bas semble être d'environ 200 $ pour envoyer un million de spams. C'est très bon marché, 1/50ème de centime par spam. Mais filtrer 95 % du spam, par exemple, augmenterait le coût pour les spammeurs d'atteindre une audience donnée d'un facteur 20. Peu d'entre eux peuvent avoir des marges suffisamment importantes pour absorber cela.
[3] En règle générale, plus il y a de qualificatifs avant le nom d'un pays, plus les dirigeants sont corrompus. Un pays appelé La République Démocratique Populaire Socialiste de X est probablement le dernier endroit au monde où vous voudriez vivre.
Remerciements à Sarah Harlin pour la lecture des brouillons ; Daniel Giffin (qui écrit également l'interpréteur Arc de production) pour plusieurs bonnes idées sur le filtrage et pour la création de notre infrastructure de messagerie ; Robert Morris, Trevor Blackwell et Erann Gat pour de nombreuses discussions sur le spam ; Raph Levien pour ses conseils sur les métriques de confiance ; et Chip Coldwell et Sam Steingold pour leurs conseils sur les statistiques.
Vous trouverez cet essai et 14 autres dans Hackers & Painters.
Plus d'infos :