Un Piano per lo Spam // A Plan for Spam
Traduzione in italiano di Paolo Zanni dall’essay originale di Paul Graham "A Plan for Spam"
Traduzione in italiano di Paolo Zanni dall’essay originale di Paul Graham "A Plan for Spam" [Agosto 2022].
Questo essay, a causa della sua struttura particolare, non è disponibile in versione audio.
(Questo articolo descrive le tecniche di filtraggio dello spam utilizzate nel lettore di posta elettronica web a prova di spam che abbiamo costruito per esercitarci con Arc. Un algoritmo migliorato è descritto in Better Bayesian Filtering).
Penso che sia possibile fermare lo spam e che i filtri basati sul contenuto siano il modo per farlo. Il tallone d'Achille degli spammer è il loro messaggio. Sono in grado di aggirare qualsiasi altra barriera che venga posta. Almeno finora ci sono riusciti. Ma devono trasmettere il loro messaggio, qualunque esso sia. Se riusciamo a scrivere un software che riconosca i loro messaggi, non c'è modo che riescano ad aggirarlo.
_ _ _
Per il destinatario, lo spam è facilmente riconoscibile. Se si assumesse qualcuno per leggere la posta e scartare lo spam, non avrebbe problemi a farlo. Quanto dobbiamo fare, a parte l'intelligenza artificiale, per automatizzare questo processo?
Penso che saremo in grado di risolvere il problema con algoritmi abbastanza semplici. Infatti, ho scoperto che è possibile filtrare in modo accettabile lo spam attuale utilizzando nient'altro che una combinazione bayesiana delle probabilità di spam delle singole parole. Utilizzando un filtro bayesiano leggermente modificato (come descritto di seguito), ci sfuggono meno di 5 spam su 1000, con 0 falsi positivi.
L'approccio statistico di solito non è il primo che si tenta quando si scrivono filtri antispam. Il primo istinto della maggior parte degli hacker è quello di cercare di scrivere un software che riconosca le singole proprietà dello spam. Guardate lo spam e pensate: che faccia tosta hanno questi tizi a cercare di inviarmi una mail che inizia con “Caro amico” o che ha un oggetto tutto maiuscolo e che finisce con otto punti esclamativi. Posso filtrare queste cose con una sola riga di codice.
E così si fa, e all'inizio funziona. Poche e semplici regole eliminano un bel po' di spam in entrata. La semplice ricerca della parola “click” cattura il 79,7% delle e-mail nel mio corpus di spam, con solo l'1,2% di falsi positivi.
Ho passato circa sei mesi a scrivere un software che cercava le singole caratteristiche dello spam prima di provare l'approccio statistico. Ho scoperto che riconoscere gli ultimi percentili di spam diventava molto difficile e che, rendendo i filtri più stringenti, si ottenevano più falsi positivi.
I falsi positivi sono e-mail legittime che vengono erroneamente identificate come spam. Per la maggior parte degli utenti, perdere e-mail legittime è un ordine di grandezza peggiore che ricevere spam, quindi un filtro che produce falsi positivi è come una cura per l'acne che comporta un rischio di morte per il paziente.
Più spam riceve un utente, meno è probabile che si accorga di una mail legittima che giace nella sua cartella spam. E stranamente, più i filtri antispam migliorano, più i falsi positivi diventano pericolosi, perché quando i filtri sono veramente buoni, gli utenti sono più propensi a ignorare tutto ciò che catturano.
Non so perché ho evitato di provare l'approccio statistico per così tanto tempo. Penso che sia stato perché mi ero abituato a cercare di identificare da solo le caratteristiche dello spam, come se stessi giocando una sorta di partita competitiva con gli spammer. (I non hacker spesso non se ne rendono conto, ma la maggior parte degli hacker è molto competitiva). Quando ho provato l'analisi statistica, ho scoperto subito che era molto più intelligente di quanto fossi io. Ha scoperto, naturalmente, che termini come “virtumundo” e “teens” sono buoni indicatori di spam. Ma ha anche scoperto che “per”, “FL” e “ff0000” sono buoni indicatori di spam. In effetti, “ff0000” (html per rosso vivo) risulta essere un buon indicatore di spam quanto qualsiasi termine pornografico.
_ _ _
Ecco una sintesi di come eseguo il filtraggio statistico. Inizio con un corpus di spam e uno di posta non spam. Al momento ciascuno di essi contiene circa 4000 messaggi. Esamino l'intero testo, comprese le intestazioni, l'html e il javascript incorporati, di ogni messaggio di ciascun corpus. Attualmente considero i caratteri alfanumerici, i trattini, gli apostrofi e i segni di dollaro come parte dei token e tutto il resto come separatore di token. (Ignoro i token che sono tutte cifre e ignoro anche i commenti html, non considerandoli nemmeno come separatori di token.
Conto il numero di volte in cui ogni token (ignorando il case, per ora) ricorre in ogni corpus. A questo punto mi ritrovo con due grandi tabelle di hash, una per ogni corpus, che mappano i token sul numero di occorrenze.
Quindi creo una terza tabella di hash, questa volta mappando ogni token sulla probabilità che un'e-mail che lo contiene sia uno spam, che calcolo come segue1:
(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)))))))))
dove word è il token di cui stiamo calcolando la probabilità, good e bad sono le tabelle hash create nel primo passo e ngood e nbad sono rispettivamente il numero di messaggi non spam e spam.
Ho riportato il codice per mostrare un paio di dettagli importanti. Voglio alterare leggermente le probabilità per evitare i falsi positivi e, per tentativi, ho scoperto che un buon modo per farlo è raddoppiare tutti i numeri in positivo. Questo aiuta a distinguere tra le parole che si trovano occasionalmente nelle e-mail legittime e quelle che non si trovano quasi mai. Considero solo le parole che ricorrono più di cinque volte in totale (in realtà, a causa del raddoppio, sarebbe sufficiente che ricorressero tre volte nelle e-mail non di spam). C'è poi la questione della probabilità da assegnare alle parole che ricorrono in un corpus ma non nell'altro. Anche in questo caso, per tentativi, ho scelto 0,01 e 0,99. Ci può essere spazio per la messa a punto, ma con la crescita del corpus tale messa a punto avverrà comunque automaticamente.
I più attenti noteranno che, mentre considero ogni corpus come un unico lungo flusso di testo ai fini del conteggio delle occorrenze, per calcolare le probabilità di spam uso il numero di e-mail in ciascuno di essi, piuttosto che la loro lunghezza combinata. Questo aggiunge un'altra leggera distorsione per proteggere dai falsi positivi.
Quando arriva un nuovo messaggio, questo viene scomposto in token e i quindici token più interessanti, dove l'interesse è misurato in base a quanto la loro probabilità di spam è lontana da un valore neutro di 0,5, vengono utilizzati per calcolare la probabilità che la posta sia spam. Se probs è un elenco delle quindici probabilità individuali, si calcola la probabilità combinata in questo modo:
(let ((prod (apply #'* probs)))
(/ prod (+ prod (apply #'* (mapcar #'(lambda (x)
(- 1 x))
probs)))))
Una domanda che sorge nella pratica è quale probabilità assegnare a una parola mai vista, cioè che non compare nella tabella delle probabilità delle parole. Ho scoperto, sempre per tentativi, che .4 è un buon numero da utilizzare. Se non avete mai visto una parola prima d'ora, è probabile che sia buona; le parole spam tendono a essere fin troppo familiari.
In un'appendice alla fine sono riportati esempi di applicazione di questo algoritmo a messaggi di posta elettronica reali.
Considero spam una mail se l'algoritmo di cui sopra le dà una probabilità superiore a .9 di esserlo. In pratica, però, non ha molta importanza dove si colloca questa soglia, perché poche probabilità finiscono nel mezzo dell'intervallo.
_ _ _
Un grande vantaggio dell'approccio statistico è che non si devono leggere così tanti messaggi di spam. Negli ultimi sei mesi ho letto letteralmente migliaia di messaggi di spam ed è davvero demoralizzante. Norbert Wiener diceva che se si compete con gli schiavi si diventa schiavi, e c'è qualcosa di altrettanto degradante nel competere con gli spammer. Per riconoscere le singole caratteristiche dello spam bisogna cercare di entrare nella mente dello spammer, e francamente voglio passare il minor tempo possibile nella mente degli spammer.
Ma il vero vantaggio dell'approccio bayesiano, ovviamente, è che si sa cosa si sta misurando. I filtri che riconoscono le caratteristiche, come SpamAssassin, assegnano un “punteggio” di spam alle e-mail. L'approccio bayesiano assegna una probabilità effettiva. Il problema di un “punteggio” è che nessuno sa cosa significhi. Non lo sa l'utente, ma peggio ancora non lo sa lo sviluppatore del filtro. Quanti punti dovrebbe ricevere un'e-mail se contiene la parola “sesso”? Una probabilità può ovviamente essere sbagliata, ma c'è poca ambiguità sul suo significato o sul modo in cui le prove dovrebbero essere combinate per calcolarla. Sulla base del mio corpus, “sesso” indica una probabilità di .97 che l'email contenente sia uno spam, mentre “sexy” indica una probabilità di .99. La regola di Bayes, altrettanto inequivocabile, dice che un'e-mail contenente entrambe le parole avrebbe, in assenza (improbabile) di altre prove, il 99,97% di probabilità di essere spam.
Poiché misura le probabilità, l'approccio bayesiano considera tutte le prove presenti nell'e-mail, sia quelle positive che quelle negative. Le parole che ricorrono sproporzionatamente di rado nello spam (come “però” o “stasera” o “a quanto pare”) contribuiscono a diminuire la probabilità tanto quanto parole negative come “unsubscribe” e “opt-in” contribuiscono ad aumentarla. Quindi un'e-mail altrimenti legittima che includa la parola “sesso” non verrà etichettata come spam.
Idealmente, naturalmente, le probabilità dovrebbero essere calcolate individualmente per ogni utente. Ricevo molte e-mail contenenti la parola “Lisp” e (finora) nessuno spam. Quindi una parola del genere è di fatto una sorta di password per l'invio di posta elettronica a me. Nel mio precedente software di filtraggio dello spam, l'utente poteva impostare un elenco di tali parole e la posta che le conteneva superava automaticamente i filtri. Nel mio elenco ho inserito parole come “Lisp” e anche il mio codice di avviamento postale, in modo da far passare le ricevute degli ordini online (che altrimenti avrebbero avuto un suono piuttosto spammoso). Pensavo di essere molto intelligente, ma ho scoperto che il filtro bayesiano faceva la stessa cosa per me, e inoltre ha scoperto molte parole a cui non avevo pensato.
Quando all'inizio ho detto che i nostri filtri lasciano passare meno di 5 spam su 1000 con 0 falsi positivi, mi riferisco al filtraggio della mia posta basato su un corpus di posta. Ma questi numeri non sono fuorvianti, perché questo è l'approccio che sto sostenendo: filtrare la posta di ogni utente in base alla posta spam e non spam che riceve. In sostanza, ogni utente dovrebbe avere due pulsanti di cancellazione, quello ordinario e quello per la cancellazione come spam. Tutto ciò che viene cancellato come spam va nel corpus dello spam, mentre tutto il resto va nel corpus del non spam.
Si potrebbe inizializzare gli utenti con un filtro di partenza, ma alla fine ogni utente dovrebbe avere le proprie probabilità per parola basate sulla posta che riceve. Questo (a) rende i filtri più efficaci, (b) permette a ogni utente di decidere la propria definizione precisa di spam e (c) forse, soprattutto, rende difficile per gli spammer sintonizzare le mail per farle passare attraverso i filtri. Se gran parte del cervello del filtro risiede nei singoli database, la semplice messa a punto degli spam per farli passare attraverso i filtri di partenza non garantirà nulla sulla loro capacità di passare attraverso i filtri diversi e molto più addestrati dei singoli utenti.
Il filtro antispam basato sui contenuti è spesso combinato con una whitelist, un elenco di mittenti la cui posta può essere accettata senza alcun filtro. Un modo semplice per creare una whitelist di questo tipo consiste nel tenere un elenco di tutti gli indirizzi a cui l'utente ha inviato posta. Se un lettore di posta elettronica dispone di un pulsante di cancellazione come spam, si può anche aggiungere l'indirizzo di provenienza di ogni e-mail che l'utente ha cancellato come spazzatura ordinaria.
Sono un sostenitore delle whitelist, ma più per risparmiare calcoli che per migliorare il filtraggio. Ero abituato a pensare che le whitelist avrebbero reso più semplice il filtraggio, in quanto si sarebbero dovute filtrare solo le e-mail di persone che non si erano mai sentite, mentre chi vi invia una e-mail per la prima volta è limitato dalle convenzioni su ciò che può dirvi. Una persona che conoscete già potrebbe inviarvi un'e-mail che parla di sesso, ma una persona che vi invia una e-mail per la prima volta non lo farebbe. Il problema è che le persone possono avere più di un indirizzo e-mail, quindi un nuovo indirizzo mittente non garantisce che il mittente vi stia scrivendo per la prima volta. Non è insolito che un vecchio amico (soprattutto se si tratta di un hacker) vi invii improvvisamente un'e-mail con un nuovo indirizzo di provenienza, quindi non potete rischiare falsi positivi filtrando in modo particolarmente rigoroso la posta proveniente da indirizzi sconosciuti.
In un certo senso, però, i miei filtri rappresentano una sorta di whitelist (e blacklist) perché si basano su interi messaggi, comprese le intestazioni. Quindi, in un certo senso, “conoscono” gli indirizzi e-mail dei mittenti affidabili e persino i percorsi attraverso i quali la posta arriva da loro a me. E sanno lo stesso dello spam, compresi i nomi dei server, le versioni dei mailer e i protocolli.
_ _ _
Se pensassi di poter mantenere gli attuali tassi di filtraggio dello spam, considererei il problema risolto. Ma non significa molto essere in grado di filtrare la maggior parte dello spam attuale, perché lo spam si evolve. Infatti, la maggior parte delle tecniche antispam finora sono state come pesticidi che non fanno altro che creare un nuovo ceppo di insetti resistenti.
Sono più fiducioso nei confronti dei filtri bayesiani, perché si evolvono con lo spam. Quindi, se gli spammer iniziano a usare “c0ck” invece di “cock” per eludere i filtri antispam semplicistici basati sulle singole parole, i filtri bayesiani se ne accorgono automaticamente. In effetti, “c0ck” è una prova molto più dannosa di “cock”, e i filtri bayesiani sanno esattamente quanto di più.
Tuttavia, chiunque proponga un piano per il filtraggio dello spam deve essere in grado di rispondere alla domanda: se gli spammer sapessero esattamente cosa state facendo, quanto riuscirebbero a superarvi? Ad esempio, penso che se il filtraggio dello spam basato sul checksum diventasse un serio ostacolo, gli spammer passerebbero a tecniche mad-lib per generare i corpi dei messaggi.
Per battere i filtri bayesiani, non basterebbe che gli spammer rendessero uniche le loro e-mail o smettessero di usare singole parole sconce. Dovrebbero rendere le loro e-mail indistinguibili dalla posta ordinaria. E questo credo che li limiterebbe molto. Lo spam è costituito per lo più da annunci di vendita, quindi, a meno che la vostra posta ordinaria non sia tutta annunci di vendita, gli spam avranno inevitabilmente un carattere diverso. Inoltre, gli spammer dovrebbero cambiare (e continuare a cambiare) la loro intera infrastruttura, perché altrimenti le intestazioni risulterebbero ai filtri bayesiani come sempre negative, indipendentemente da ciò che hanno fatto al corpo del messaggio. Non conosco abbastanza l'infrastruttura utilizzata dagli spammer per sapere quanto sarebbe difficile far apparire legittime le intestazioni, ma la mia ipotesi è che sarebbe ancora più difficile che far apparire legittimo il messaggio.
Ammesso che si riesca a risolvere il problema delle intestazioni, lo spam del futuro avrà probabilmente un aspetto simile a questo:
Ciao a tutti. Ho pensato che dovessi dare un'occhiata a quanto segue: http://www.27meg.com/foo
perché questo è il massimo della vendita che i filtri basati sul contenuto lasceranno allo spammer. (In effetti, sarà difficile anche superare i filtri, perché se tutto il resto dell'e-mail è neutro, la probabilità di spam si baserà sull'URL, e ci vorrà un certo sforzo per farlo sembrare neutro).
Gli spammer vanno dalle aziende che gestiscono le cosiddette liste opt-in e che non cercano nemmeno di nascondere la propria identità, a chi dirotta i server di posta per inviare spam che promuove siti porno. Se usiamo il filtraggio per ridurre le loro opzioni a mail come quella qui sopra, gli spammer che si trovano all'estremità “legittima” dello spettro dovrebbero essere praticamente fuori dal mercato; si sentono obbligati da varie leggi statali a includere un testo che spiega perché il loro spam non è spam e come annullare la “sottoscrizione”, e questo tipo di testo è facile da riconoscere.
(Una volta pensavo che fosse ingenuo credere che leggi più severe avrebbero diminuito lo spam. Ora penso che, sebbene leggi più severe possano non diminuire la quantità di spam che gli spammer inviano, possono certamente aiutare i filtri a diminuire la quantità di spam che i destinatari vedono effettivamente).
In ogni caso, se si limitano le vendite che gli spammer possono fare, si tende inevitabilmente a farli fallire. La parola affari è importante da ricordare. Gli spammer sono uomini d'affari. Inviano spam perché funziona. Funziona perché, sebbene il tasso di risposta sia abominevolmente basso (al massimo 15 su un milione, contro i 3.000 su un catalogo), il costo, per loro, è praticamente nullo. Il costo è enorme per i destinatari, circa 5 settimane-uomo per ogni milione di destinatari che spendono un secondo per cancellare lo spam, ma lo spammer non deve pagarlo.
L'invio di spam ha comunque un costo per lo spammer.2 Quindi, quanto più si riesce a ridurre il tasso di risposta, sia con il filtraggio che con l'uso di filtri che costringano gli spammer a diluire le loro proposte, tanto meno le aziende troveranno conveniente inviare spam.
Il motivo per cui gli spammer utilizzano il tipo di messaggi di vendita che utilizzano è quello di aumentare i tassi di risposta. Questo è forse ancora più disgustoso che entrare nella mente di uno spammer, ma diamo un rapido sguardo alla mente di chi risponde allo spam. Questa persona o è incredibilmente credulona o nega profondamente i propri interessi sessuali. In entrambi i casi, per quanto lo spam ci sembri ripugnante o idiota, per loro è eccitante. Gli spammer non direbbero queste cose se non sembrassero eccitanti. E “ho pensato che dovreste dare un'occhiata a quanto segue” non ha la stessa attrattiva sul destinatario dello spam del tipo di cose che gli spammer dicono ora. Risultato: se non può contenere proposte di vendita interessanti, lo spam diventa meno efficace come veicolo di marketing e meno aziende vogliono usarlo.
Alla fine è questa la grande vittoria. Ho iniziato a scrivere software per il filtraggio dello spam perché non volevo più guardare quella roba. Ma se diventiamo abbastanza bravi a filtrare lo spam, smetterà di funzionare e gli spammer smetteranno di inviarlo.
_ _ _
Tra tutti gli approcci alla lotta allo spam, dal software alle leggi, credo che il filtro bayesiano sarà il più efficace. Ma penso anche che più tipi diversi di sforzi antispam intraprendiamo, meglio è, perché qualsiasi misura che limiti gli spammer tenderà a rendere più facile il filtraggio. Anche nell'ambito del filtraggio basato sui contenuti, ritengo che sia positivo che vengano utilizzati contemporaneamente molti tipi diversi di software. Più filtri diversi ci sono, più sarà difficile per gli spammer mettere a punto gli spam per superarli.
Appendice: Esempi di filtraggio
Ecco un esempio di spam arrivato mentre stavo scrivendo questo articolo. Le quindici parole più interessanti di questo spam sono:
qvp0045
indira
mx-05
intimail
$7500
freeyankeedom
cdo
bluefoxmedia
jpg
unsecured
platinum
3d0
qves
7c5
7c266675
Le parole sono un mix di elementi provenienti dalle intestazioni e dal corpo del messaggio, il che è tipico dello spam. Tipico dello spam è anche il fatto che ognuna di queste parole ha una probabilità di spam, nel mio database, di .99. In realtà ci sono più di quindici parole con una probabilità di .99, e queste sono solo le prime quindici viste.
Purtroppo ciò rende questa e-mail un esempio noioso dell'uso della Regola di Bayes. Per vedere un'interessante varietà di probabilità dobbiamo osservare questo spam, in realtà piuttosto atipico.
Le quindici parole più interessanti di questo spam, con le relative probabilità, sono:
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
Questa volta le evidenze sono un misto di buone e cattive. Una parola come “shortest” è una evidenza di legittimità quasi pari a quella di una parola come “madam” o “promotion” per la colpevolezza. Ma la tesi della colpevolezza è comunque più forte. Se si combinano questi numeri secondo la regola di Bayes, la probabilità risultante è .9027.
“Madam” proviene ovviamente dagli spam che iniziano con Dear Sir or Madam’. Non sono molto comuni, ma la parola “Madam” non compare mai nelle mie e-mail legittime, ed è tutta una questione di rapporto.
“Republic” ottiene un punteggio elevato perché compare spesso nelle e-mail di truffa nigeriane e compare anche una o due volte negli spam che fanno riferimento alla Corea e al Sudafrica. Si potrebbe dire che è un caso che aiuti a identificare questo spam. Ma esaminando le probabilità dello spam ho scoperto che di questi incidenti ce ne sono molti e che hanno la straordinaria tendenza a spingere le cose nella direzione giusta piuttosto che in quella sbagliata. In questo caso, non è del tutto una coincidenza che la parola “Republic” ricorra nelle e-mail di truffa nigeriane e in questo spam. Esiste un'intera classe di proposte commerciali dubbie che coinvolgono paesi meno sviluppati, e questi a loro volta hanno più probabilità di avere nomi che specificano esplicitamente (perché non lo sono) che si tratta di repubbliche.3
D'altra parte, “enter” è un vero e proprio errore. Si verifica soprattutto nelle istruzioni di disiscrizione, ma in questo caso è usato in modo del tutto legittimo. Fortunatamente l'approccio statistico è abbastanza robusto e può tollerare un certo numero di errori prima che i risultati inizino a essere sballati.
A titolo di confronto, ecco un esempio di un caso raro, uno spam che supera i filtri. Perché? Perché, per puro caso, contiene parole che ricorrono nelle mie e-mail reali:
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
Ci sono un paio di buone notizie. Innanzitutto, questa mail probabilmente non passerebbe attraverso i filtri di chi non è specializzato in linguaggi di programmazione e ha un buon amico di nome Morris. Per un utente medio, tutte le prime cinque parole sarebbero neutre e non contribuirebbero alla probabilità di spam.
In secondo luogo, ritengo che il filtraggio basato sulle coppie di parole (vedi sotto) potrebbe essere in grado di catturare questo caso: “cost effective”, “setup fee”, “money back” - roba piuttosto incriminante. E naturalmente se continuassero a spammare me (o una rete di cui faccio parte), “Hostex” stesso verrebbe riconosciuto come un termine di spam.
Infine, ecco un'e-mail legittima. Le quindici parole più interessanti sono le seguenti:
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 maggior parte delle parole presenti indica che si tratta di una mail leggittima. Ci sono due parole sospette, “color” (gli spammer amano i font colorati) e “California” (che ricorre nei testimonial e anche nei menu dei moduli), ma non sono sufficienti a superare parole ovviamente legittime come “continuazione” ed “esempio”.
È interessante che “describe” sia considerato così del tutto leittimo. Non si è verificato in nessuno dei miei 4000 spam. I dati si rivelano pieni di sorprese. Una delle cose che si imparano analizzando i testi di spam è quanto sia ristretto il sottoinsieme della lingua in cui operano gli spammer. È questo fatto, insieme al vocabolario altrettanto caratteristico della posta di ogni singolo utente, che rende il filtraggio bayesiano una buona scommessa.
Appendice: Altre idee
Un'idea che non ho ancora provato è quella di filtrare in base alle coppie di parole, o addirittura alle triple, piuttosto che alle singole parole. In questo modo si dovrebbe ottenere una stima molto più precisa della probabilità. Ad esempio, nel mio database attuale, la parola “offers” ha una probabilità di 0,96. Se si basasse la probabilità sulle coppie di parole, si otterrebbe che “special offers” e “valuable offers” hanno una probabilità di .99 e, ad esempio, “approach offers” (come “this approach offers”) ha una probabilità di .1 o meno.
Il motivo per cui non l'ho fatto è che il filtro basato sulle singole parole funziona già molto bene. Tuttavia, ciò significa che c'è spazio per rafforzare i filtri se lo spam diventa più difficile da individuare. (Curiosamente, un filtro basato su coppie di parole sarebbe in effetti un generatore di testo a catena di Markov che funziona al contrario).
Caratteristiche specifiche dello spam (ad esempio, non vedere l'indirizzo del destinatario nel campo to:) hanno ovviamente un valore nel riconoscimento dello spam. Possono essere considerate in questo algoritmo trattandole come parole virtuali. Probabilmente lo farò nelle prossime versioni, almeno per una manciata di indicatori di spam più evidenti. I filtri antispam che riconoscono le caratteristiche sono corretti in molti dettagli; ciò che manca è una disciplina generale per combinare le evidenze.
Il riconoscimento delle caratteristiche non spam può essere più importante di quello delle caratteristiche spam. I falsi positivi sono una preoccupazione tale da richiedere misure straordinarie. Probabilmente nelle prossime versioni aggiungerò un secondo livello di test progettato specificamente per evitare i falsi positivi. Se una mail attiva questo secondo livello di filtri, verrà accettata anche se la sua probabilità di spam è superiore alla soglia.
Non mi aspetto che questo secondo livello di filtraggio sia bayesiano. Sarà inevitabilmente non solo ad hoc, ma anche basato su ipotesi, perché il numero di falsi positivi non tenderà a essere abbastanza grande da notare gli schemi. (In ogni caso, è bene che un sistema di backup non si basi sulla stessa tecnologia del sistema principale).
Un'altra cosa che potrei provare a fare in futuro è concentrare l'attenzione su parti specifiche dell'e-mail. Ad esempio, circa il 95% dello spam attuale include l'url di un sito che vogliono farvi visitare. (Il restante 5% vuole che chiamiate un numero di telefono, che rispondiate via e-mail o a un indirizzo di posta americano o, in pochi casi, che compriate una certa azione). In questi casi l'URL è praticamente sufficiente da solo a determinare se l'e-mail è spam.
I nomi di dominio si distinguono dal resto del testo di un'e-mail (non in tedesco) perché spesso sono costituiti da più parole unite tra loro. Sebbene sia computazionalmente costoso nel caso generale, potrebbe valere la pena provare a scomporli. Se un filtro non ha mai visto il token “xxxporn” prima d'ora, avrà una probabilità di spam individuale di .4, mentre “xxx” e “porn” singolarmente hanno probabilità (nel mio corpus) di .9889 e .99 rispettivamente, e una probabilità combinata di .9998.
Mi aspetto che la scomposizione dei nomi di dominio diventi sempre più importante, dato che gli spammer saranno gradualmente costretti a non utilizzare più parole incriminanti nel testo dei loro messaggi. (Un url con un indirizzo ip è ovviamente un segno estremamente incriminante, tranne che nella posta di alcuni sysadmin).
Potrebbe essere una buona idea avere un elenco gestito in modo cooperativo di url promossi dagli spammer. Avremmo bisogno di una metrica di fiducia del tipo studiato da Raph Levien per evitare invii malevoli o incompetenti, ma se avessimo una cosa del genere fornirebbe una spinta a qualsiasi software di filtraggio. Sarebbe anche una comoda base per i boicottaggi.
Un altro modo per testare gli URL dubbi sarebbe quello di inviare un crawler per esaminare il sito prima che l'utente guardi l'e-mail che lo menziona. Si potrebbe utilizzare un filtro bayesiano per valutare il sito proprio come si farebbe con un'e-mail, e tutto ciò che viene trovato sul sito potrebbe essere incluso nel calcolo della probabilità che l'e-mail sia uno spam. Un url che porta a un reindirizzamento sarebbe ovviamente particolarmente sospetto.
Un progetto di cooperazione che credo sarebbe davvero una buona idea sarebbe quello di accumulare un corpus gigante di spam. Un corpus ampio e pulito è la chiave per far funzionare bene il filtraggio bayesiano. I filtri bayesiani potrebbero effettivamente utilizzare il corpus come input. Ma un corpus del genere sarebbe utile anche per altri tipi di filtri, perché potrebbe essere usato per testarli.
La creazione di un tale corpus pone alcuni problemi tecnici. Avremmo bisogno di metriche di fiducia per evitare invii maligni o incompetenti, ovviamente. Avremmo anche bisogno di modi per cancellare le informazioni personali (non solo gli indirizzi di posta elettronica e i codici, ma anche, ad esempio, gli argomenti degli url di cancellazione, che spesso codificano l'indirizzo di posta elettronica) dalle mail del corpus. Se qualcuno vuole intraprendere questo progetto, sarebbe una buona cosa per il mondo.
Appendice: Definizione di spam
Credo che ci sia un consenso approssimativo su cosa sia lo spam, ma sarebbe utile avere una definizione esplicita. Dovremo farlo se vogliamo stabilire un corpus centrale di spam, o anche per confrontare in modo significativo i tassi di filtraggio dello spam.
Per cominciare, lo spam non è un'e-mail commerciale non richiesta. Se qualcuno nel mio quartiere sapesse che sto cercando una vecchia Raleigh a tre velocità in buone condizioni e mi inviasse un'e-mail offrendomi di vendermene una, ne sarei felice, eppure questa e-mail sarebbe sia commerciale che non richiesta. La caratteristica distintiva dello spam (in effetti, la sua ragion d'essere) non è che non sia richiesto, ma che sia automatizzato.
Anche il fatto che lo spam sia solitamente commerciale è puramente incidentale. Se qualcuno iniziasse a inviare e-mail di massa per sostenere una causa politica, ad esempio, sarebbe spam tanto quanto le e-mail che promuovono un sito porno.
Propongo di definire lo spam come e-mail automatiche non richieste. Questa definizione include quindi alcune e-mail che molte definizioni legali di spam non includono. Le definizioni legali di spam, influenzate presumibilmente dalle lobby, tendono a escludere la posta inviata da aziende che hanno un “rapporto esistente” con il destinatario. Ma l'acquisto di qualcosa da un'azienda, ad esempio, non implica che si sia sollecitato un continuo invio di e-mail da parte sua. Se ordino qualcosa da un negozio online e poi mi inviano un flusso di spam, si tratta comunque di spam.
Le aziende che inviano spam spesso forniscono un modo per “annullare l'iscrizione” o chiedono di andare sul loro sito e modificare le “preferenze dell'account” se si vuole smettere di ricevere spam. Questo non è sufficiente a impedire che la posta sia spam. Non scegliere l'opt-out non è come scegliere l'adesione. A meno che il destinatario non abbia spuntato esplicitamente una casella chiaramente etichettata (il cui valore predefinito è no) chiedendo di ricevere l'e-mail, allora si tratta di spam.
In alcuni rapporti commerciali, si sollecita implicitamente un certo tipo di posta. Quando si ordina online, credo che si richieda implicitamente una ricevuta e una notifica quando l'ordine viene spedito. Non mi dispiace quando Verisign mi invia un messaggio di posta elettronica per avvisarmi che un nome di dominio sta per scadere (almeno, se sono loro a registrarlo). Ma quando Verisign mi invia un messaggio di posta elettronica offrendo una Guida GRATUITA alla creazione di un sito Web di e-commerce, questo è spam.
Grazie a Sarah Harlin per aver letto le bozze di questo testo; a Daniel Giffin (che sta anche scrivendo l'interprete Arc di produzione) per molte buone idee sul filtraggio e per aver creato la nostra infrastruttura di posta; a Robert Morris, Trevor Blackwell e Erann Gat per molte discussioni sullo spam; a Raph Levien per i consigli sulle metriche di fiducia; a Chip Coldwell e Sam Steingold per i consigli sulle statistiche.
Note
Gli esempi di questo articolo sono tradotti in Common Lisp per, che ci crediate o no, una maggiore accessibilità. L'applicazione qui descritta è quella che abbiamo scritto per testare un nuovo dialetto Lisp chiamato Arc, non ancora rilasciato.
Attualmente la tariffa più bassa sembra essere di circa 200 dollari per inviare un milione di spam. Si tratta di un prezzo molto basso, 1/50 di centesimo di dollaro per spam. Ma filtrare il 95% dello spam, ad esempio, aumenterebbe di 20 volte il costo che gli spammer devono sostenere per raggiungere un determinato pubblico. Pochi possono avere margini abbastanza grandi da assorbire questa cifra.
Come regola generale, più qualificativi ci sono prima del nome di un Paese, più corrotti sono i governanti. Un Paese chiamato Repubblica Democratica Popolare Socialista di X è probabilmente l'ultimo posto al mondo in cui si vorrebbe vivere.