Un Plan Contra el Spam

¿Te gusta construir cosas? Prueba Hacker News.


Agosto 2002

(Este artículo describe las técnicas de filtrado de spam utilizadas en el lector de correo web a prueba de spam que construimos para ejercitar Arc. Un algoritmo mejorado se describe en Mejor Filtrado Bayesiano.)

Creo que es posible detener el spam, y que los filtros basados en contenido son el camino a seguir. El talón de Aquiles de los spammers es su mensaje. Pueden eludir cualquier otra barrera que les pongas. Lo han hecho hasta ahora, al menos. Pero tienen que entregar su mensaje, sea cual sea. Si podemos escribir software que reconozca sus mensajes, no hay forma de que puedan evitarlo.


A la persona que recibe el spam, este le resulta fácilmente reconocible. Si contrataras a alguien para que leyera tu correo y descartara el spam, tendría pocas dificultades en hacerlo. ¿Cuánto tenemos que hacer, sin llegar a la IA, para automatizar este proceso?

Creo que podremos resolver el problema con algoritmos bastante sencillos. De hecho, he descubierto que se puede filtrar el spam actual de forma aceptable utilizando nada más que una combinación bayesiana de las probabilidades de spam de palabras individuales. Usando un filtro bayesiano ligeramente ajustado (como se describe a continuación), ahora perdemos menos de 5 de cada 1000 spams, con 0 falsos positivos.

El enfoque estadístico no suele ser el primero que la gente intenta al escribir filtros de spam. El primer instinto de la mayoría de los hackers es intentar escribir software que reconozca las propiedades individuales del spam. Miras los spams y piensas, la audacia de estos tipos al intentar enviarme correos que empiezan con "Estimado amigo" o con una línea de asunto que está toda en mayúsculas y termina en ocho signos de exclamación. Puedo filtrar esas cosas con una sola línea de código.

Y así lo haces, y al principio funciona. Unas pocas reglas sencillas reducirán considerablemente tu spam entrante. Simplemente buscar la palabra "clic" capturará el 79,7% de los correos electrónicos de mi corpus de spam, con solo un 1,2% de falsos positivos.

Pasé unos seis meses escribiendo software que buscaba características individuales de spam antes de probar el enfoque estadístico. Lo que descubrí fue que reconocer ese último pequeño porcentaje de spams se volvió muy difícil, y que al hacer los filtros más estrictos, obtuve más falsos positivos.

Los falsos positivos son correos electrónicos inocentes que se identifican erróneamente como spam. Para la mayoría de los usuarios, perder un correo legítimo es un orden de magnitud peor que recibir spam, por lo que un filtro que produce falsos positivos es como una cura para el acné que conlleva un riesgo de muerte para el paciente.

Cuanto más spam recibe un usuario, menos probable es que note un correo inocente en su carpeta de spam. Y, extrañamente, cuanto mejores sean tus filtros de spam, más peligrosos se vuelven los falsos positivos, porque cuando los filtros son realmente buenos, los usuarios tenderán a ignorar todo lo que capturan.

No sé por qué tardé tanto en intentar el enfoque estadístico. Creo que fue porque me volví adicto a intentar identificar las características del spam yo mismo, como si estuviera jugando a algún tipo de juego competitivo con los spammers. (Los no hackers no se dan cuenta de esto a menudo, pero la mayoría de los hackers son muy competitivos.) Cuando probé el análisis estadístico, descubrí inmediatamente que era mucho más inteligente que yo. Descubrió, por supuesto, que términos como "virtumundo" y "teens" eran buenos indicadores de spam. Pero también descubrió que "per", "FL" y "ff0000" son buenos indicadores de spam. De hecho, "ff0000" (html para rojo brillante) resulta ser un indicador de spam tan bueno como cualquier término pornográfico.


Aquí tienes un esquema de cómo hago el filtrado estadístico. Empiezo con un corpus de spam y uno de correos no spam. En este momento, cada uno tiene alrededor de 4000 mensajes. Escaneo todo el texto, incluyendo las cabeceras y el html y javascript incrustados, de cada mensaje en cada corpus. Actualmente considero que los caracteres alfanuméricos, guiones, apóstrofes y signos de dólar son parte de los tokens, y todo lo demás es un separador de tokens. (Probablemente haya margen de mejora aquí.) Ignoro los tokens que son solo dígitos, y también ignoro los comentarios html, sin siquiera considerarlos como separadores de tokens.

Cuento el número de veces que cada token (ignorando mayúsculas/minúsculas, actualmente) aparece en cada corpus. En esta etapa, termino con dos grandes tablas hash, una para cada corpus, que mapean tokens a número de ocurrencias.

A continuación, creo una tercera tabla hash, esta vez mapeando cada token a la probabilidad de que un correo electrónico que lo contenga sea spam, que calculo de la siguiente manera [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))))))))) donde word es el token cuya probabilidad estamos calculando, good y bad son las tablas hash que creé en el primer paso, y ngood y nbad son el número de mensajes no spam y spam respectivamente.

Expliqué esto como código para mostrar un par de detalles importantes. Quiero sesgar las probabilidades ligeramente para evitar falsos positivos, y por prueba y error he descubierto que una buena manera de hacerlo es duplicar todos los números en good. Esto ayuda a distinguir entre palabras que ocasionalmente aparecen en correos electrónicos legítimos y palabras que casi nunca lo hacen. Solo considero palabras que ocurren más de cinco veces en total (de hecho, debido a la duplicación, ocurrir tres veces en correos no spam sería suficiente). Y luego está la cuestión de qué probabilidad asignar a las palabras que ocurren en un corpus pero no en el otro. De nuevo, por prueba y error elegí .01 y .99. Puede haber margen de ajuste aquí, pero a medida que el corpus crezca, dicho ajuste ocurrirá automáticamente de todos modos.

Los especialmente observadores notarán que, si bien considero cada corpus como una única y larga secuencia de texto para fines de conteo de ocurrencias, utilizo el número de correos electrónicos en cada uno, en lugar de su longitud combinada, como divisor en el cálculo de las probabilidades de spam. Esto añade otro ligero sesgo para proteger contra falsos positivos.

Cuando llega un nuevo correo, se escanea en tokens, y los quince tokens más interesantes, donde interesante se mide por cuán lejos está su probabilidad de spam de un neutro .5, se utilizan para calcular la probabilidad de que el correo sea spam. Si probs es una lista de las quince probabilidades individuales, calculas la probabilidad combinada así: (let ((prod (apply #'* probs))) (/ prod (+ prod (apply #'* (mapcar #'(lambda (x) (- 1 x)) probs))))) Una pregunta que surge en la práctica es qué probabilidad asignar a una palabra que nunca has visto, es decir, una que no aparece en la tabla hash de probabilidades de palabras. He descubierto, de nuevo por prueba y error, que .4 es un buen número para usar. Si nunca has visto una palabra antes, es probablemente bastante inocente; las palabras de spam tienden a ser demasiado familiares.

Hay ejemplos de este algoritmo aplicados a correos electrónicos reales en un apéndice al final.

Trato el correo como spam si el algoritmo anterior le da una probabilidad superior a .9 de ser spam. Pero en la práctica, no importaría mucho dónde ponga este umbral, porque pocas probabilidades terminan en el medio del rango.


Una gran ventaja del enfoque estadístico es que no tienes que leer tantos spams. Durante los últimos seis meses, he leído literalmente miles de spams, y es realmente desmoralizador. Norbert Wiener dijo que si compites con esclavos, te conviertes en un esclavo, y hay algo similarmente degradante en competir con spammers. Para reconocer características individuales de spam, tienes que intentar meterte en la mente del spammer, y francamente, quiero pasar el menor tiempo posible en la mente de los spammers.

Pero la verdadera ventaja del enfoque bayesiano, por supuesto, es que sabes lo que estás midiendo. Los filtros que reconocen características como SpamAssassin asignan una "puntuación" de spam al correo electrónico. El enfoque bayesiano asigna una probabilidad real. El problema con una "puntuación" es que nadie sabe lo que significa. El usuario no sabe lo que significa, pero lo que es peor, tampoco el desarrollador del filtro. ¿Cuántos puntos debería obtener un correo electrónico por tener la palabra "sexo"? Una probabilidad puede ser errónea, por supuesto, pero hay poca ambigüedad sobre lo que significa, o cómo se debe combinar la evidencia para calcularla. Basado en mi corpus, "sexo" indica una probabilidad de .97 de que el correo que lo contiene sea spam, mientras que "sexy" indica una probabilidad de .99. Y la Regla de Bayes, igualmente inequívoca, dice que un correo electrónico que contenga ambas palabras tendría, en ausencia (improbable) de cualquier otra evidencia, un 99,97% de posibilidades de ser spam.

Debido a que mide probabilidades, el enfoque bayesiano considera toda la evidencia en el correo electrónico, tanto buena como mala. Las palabras que ocurren desproporcionadamente raramente en el spam (como "though" o "tonight" o "apparently") contribuyen tanto a disminuir la probabilidad como las palabras malas como "unsubscribe" y "opt-in" a aumentarla. Así que un correo electrónico inocente que casualmente incluye la palabra "sexo" no será marcado como spam.

Idealmente, por supuesto, las probabilidades deberían calcularse individualmente para cada usuario. Recibo muchos correos electrónicos que contienen la palabra "Lisp", y (hasta ahora) ningún spam que lo haga. Así que una palabra como esa es efectivamente una especie de contraseña para enviarme correo. En mi software anterior de filtrado de spam, el usuario podía configurar una lista de tales palabras y los correos que las contenían pasaban automáticamente los filtros. En mi lista puse palabras como "Lisp" y también mi código postal, para que los recibos (que de otro modo sonaban bastante a spam) de pedidos en línea pasaran. Pensé que era muy inteligente, pero descubrí que el filtro bayesiano hacía lo mismo por mí, y además descubrió muchas palabras en las que no había pensado.

Cuando dije al principio que nuestros filtros dejan pasar menos de 5 spams por cada 1000 con 0 falsos positivos, estoy hablando de filtrar mi correo basándome en un corpus de mi correo. Pero estas cifras no son engañosas, porque ese es el enfoque que estoy defendiendo: filtrar el correo de cada usuario basándose en el spam y el correo no spam que recibe. Esencialmente, cada usuario debería tener dos botones de eliminar, eliminar normal y eliminar como spam. Cualquier cosa eliminada como spam va al corpus de spam, y todo lo demás va al corpus de no spam.

Podrías empezar a los usuarios con un filtro semilla, pero en última instancia, cada usuario debería tener sus propias probabilidades por palabra basadas en el correo real que recibe. Esto (a) hace que los filtros sean más efectivos, (b) permite a cada usuario decidir su propia definición precisa de spam, y (c) quizás lo mejor de todo, dificulta que los spammers ajusten sus correos para pasar los filtros. Si gran parte del cerebro del filtro está en las bases de datos individuales, entonces simplemente ajustar los spams para pasar los filtros semilla no garantizará nada sobre qué tan bien pasarán los filtros individuales variables y mucho más entrenados de cada usuario.

El filtrado de spam basado en contenido a menudo se combina con una lista blanca (whitelist), una lista de remitentes cuyo correo puede ser aceptado sin filtrado. Una forma fácil de construir tal lista blanca es mantener una lista de todas las direcciones a las que el usuario ha enviado correo alguna vez. Si un lector de correo tiene un botón de eliminar como spam, también podrías añadir la dirección del remitente de cada correo electrónico que el usuario haya eliminado como basura normal.

Soy un defensor de las listas blancas, pero más como una forma de ahorrar computación que como una forma de mejorar el filtrado. Solía pensar que las listas blancas harían el filtrado más fácil, porque solo tendrías que filtrar correos de personas de las que nunca habías oído hablar, y alguien que te envía un correo por primera vez está limitado por la convención en lo que pueden decirte. Alguien que ya conoces podría enviarte un correo hablando de sexo, pero alguien que te envía un correo por primera vez no sería propenso a hacerlo. El problema es que las personas pueden tener más de una dirección de correo electrónico, por lo que una nueva dirección de remitente no garantiza que el remitente te escriba por primera vez. No es inusual que un viejo amigo (especialmente si es un hacker) te envíe de repente un correo electrónico con una nueva dirección de remitente, por lo que no puedes arriesgarte a falsos positivos filtrando correos de direcciones desconocidas de forma especialmente rigurosa.

En cierto sentido, sin embargo, mis filtros se auto-contienen como una especie de lista blanca (y lista negra) porque se basan en mensajes completos, incluidas las cabeceras. Así que hasta ese punto "conocen" las direcciones de correo electrónico de los remitentes de confianza e incluso las rutas por las que el correo llega de ellos a mí. Y conocen lo mismo sobre el spam, incluidos los nombres de los servidores, las versiones de los programas de correo y los protocolos.


Si pensara que podría mantener las tasas actuales de filtrado de spam, consideraría este problema resuelto. Pero no significa mucho poder filtrar la mayor parte del spam actual, porque el spam evoluciona. De hecho, la mayoría de las técnicas antispam hasta ahora han sido como pesticidas que no hacen más que crear una nueva cepa de insectos resistentes.

Soy más optimista sobre los filtros bayesianos, porque evolucionan con el spam. Así que cuando los spammers empiezan a usar "c0ck" en lugar de "cock" para evadir filtros de spam simplones basados en palabras individuales, los filtros bayesianos lo notan automáticamente. De hecho, "c0ck" es una evidencia mucho más condenatoria que "cock", y los filtros bayesianos saben precisamente cuánto más.

Aun así, cualquiera que proponga un plan para el filtrado de spam tiene que ser capaz de responder a la pregunta: si los spammers supieran exactamente lo que estás haciendo, ¿qué tan bien podrían pasar? Por ejemplo, creo que si el filtrado de spam basado en checksums se convierte en un obstáculo serio, los spammers simplemente recurrirán a técnicas de "mad-lib" para generar cuerpos de mensajes.

Para vencer los filtros bayesianos, no bastaría con que los spammers hicieran sus correos electrónicos únicos o dejaran de usar palabras obscenas individuales. Tendrían que hacer que sus correos fueran indistinguibles de tu correo ordinario. Y esto, creo, los limitaría severamente. El spam son principalmente argumentos de venta, por lo que a menos que tu correo habitual sean todos argumentos de venta, los spams tendrán inevitablemente un carácter diferente. Y los spammers también tendrían que cambiar (y seguir cambiando) toda su infraestructura, porque de lo contrario las cabeceras se verían tan mal para los filtros bayesianos como siempre, sin importar lo que hicieran con el cuerpo del mensaje. No sé lo suficiente sobre la infraestructura que usan los spammers para saber lo difícil que sería hacer que las cabeceras parecieran inocentes, pero mi suposición es que sería aún más difícil que hacer que el mensaje pareciera inocente.

Suponiendo que pudieran resolver el problema de las cabeceras, el spam del futuro probablemente se parecerá a esto: "Hola. Pensé que deberías echar un vistazo a lo siguiente: http://www.27meg.com/foo" porque eso es aproximadamente todo el argumento de venta que el filtrado basado en contenido dejará al spammer. (De hecho, incluso será difícil que esto pase los filtros, porque si todo lo demás en el correo es neutral, la probabilidad de spam dependerá de la url, y requerirá cierto esfuerzo hacer que parezca neutral.)

Los spammers van desde empresas que gestionan listas de "opt-in" que ni siquiera intentan ocultar su identidad, hasta tipos que secuestran servidores de correo para enviar spams promocionando sitios pornográficos. Si usamos el filtrado para reducir sus opciones a correos como el anterior, eso debería dejar fuera de negocio a los spammers del extremo "legítimo" del espectro; se sienten obligados por diversas leyes estatales a incluir texto estándar sobre por qué su spam no es spam, y cómo cancelar su "suscripción", y ese tipo de texto es fácil de reconocer.

(Solía pensar que era ingenuo creer que leyes más estrictas disminuirían el spam. Ahora creo que, si bien leyes más estrictas pueden no disminuir la cantidad de spam que los spammers envían, ciertamente pueden ayudar a los filtros a disminuir la cantidad de spam que los destinatarios realmente ven.)

En todo el espectro, si restringes los argumentos de venta que los spammers pueden hacer, inevitablemente tenderás a sacarlos del negocio. Esa palabra negocio es importante de recordar. Los spammers son hombres de negocios. Envían spam porque funciona. Funciona porque, aunque la tasa de respuesta es abominablemente baja (en el mejor de los casos 15 por millón, frente a 3000 por millón para un envío de catálogo), el costo, para ellos, es prácticamente nulo. El costo es enorme para los destinatarios, unas 5 semanas-hombre por cada millón de destinatarios que dedican un segundo a eliminar el spam, pero el spammer no tiene que pagarlo.

Enviar spam sí le cuesta algo al spammer, sin embargo. [2] Así que cuanto más podamos reducir la tasa de respuesta, ya sea mediante filtrado, o usando filtros para obligar a los spammers a diluir sus argumentos de venta, menos negocios encontrarán que vale la pena enviar spam.

La razón por la que los spammers usan los tipos de argumentos de venta que usan es para aumentar las tasas de respuesta. Esto es posiblemente aún más asqueroso que meterse en la mente de un spammer, pero echemos un vistazo rápido a la mente de alguien que responde a un spam. Esta persona es o asombrosamente crédula o profundamente en negación sobre sus intereses sexuales. En cualquier caso, repulsivo o idiota como nos parezca el spam, es emocionante para ellos. Los spammers no dirían estas cosas si no sonaran emocionantes. Y "pensé que deberías echar un vistazo a lo siguiente" simplemente no tendrá la misma atracción para el destinatario del spam que las cosas que los spammers dicen ahora. Resultado: si no puede contener argumentos de venta emocionantes, el spam se vuelve menos efectivo como vehículo de marketing, y menos empresas querrán usarlo.

Esa es la gran victoria al final. Empecé a escribir software de filtrado de spam porque no quería tener que ver esas cosas nunca más. Pero si nos volvemos lo suficientemente buenos filtrando el spam, dejará de funcionar, y los spammers dejarán de enviarlo.


De todos los enfoques para combatir el spam, desde el software hasta las leyes, creo que el filtrado bayesiano será el más efectivo. Pero también creo que cuanto más diferentes tipos de esfuerzos antispam emprendamos, mejor, porque cualquier medida que restrinja a los spammers tenderá a facilitar el filtrado. E incluso dentro del mundo del filtrado basado en contenido, creo que será algo bueno si hay muchos tipos diferentes de software utilizándose simultáneamente. Cuantos más filtros diferentes haya, más difícil será para los spammers ajustar los spams para pasarlos.

Apéndice: Ejemplos de Filtrado

Aquí hay un ejemplo de un spam que llegó mientras escribía este artículo. Las quince palabras más interesantes en este spam son: qvp0045 indira mx-05 intimail $7500 freeyankeedom cdo bluefoxmedia jpg unsecured platinum 3d0 qves 7c5 7c266675 Las palabras son una mezcla de cosas de las cabeceras y del cuerpo del mensaje, lo cual es típico del spam. También típico del spam es que cada una de estas palabras tiene una probabilidad de spam, en mi base de datos, de .99. De hecho, hay más de quince palabras con probabilidades de .99, y estas son solo las primeras quince que se vieron.

Desafortunadamente, eso hace que este correo sea un ejemplo aburrido del uso de la Regla de Bayes. Para ver una variedad interesante de probabilidades, tenemos que mirar este spam, en realidad bastante atípico.

Las quince palabras más interesantes en este spam, con sus probabilidades, son: 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 Esta vez la evidencia es una mezcla de bueno y malo. Una palabra como "shortest" es casi tanta evidencia de inocencia como una palabra como "madam" o "promotion" lo es de culpabilidad. Pero aun así, el caso de culpabilidad es más fuerte. Si combinas estos números según la Regla de Bayes, la probabilidad resultante es .9027.

"Madam" es obviamente de spams que empiezan "Estimado Sr. o Sra.". No son muy comunes, pero la palabra "madam" nunca aparece en mi correo legítimo, y todo se trata de la proporción.

"Republic" obtiene una puntuación alta porque a menudo aparece en correos de estafa nigerianos, y también aparece una o dos veces en spams que se refieren a Corea y Sudáfrica. Se podría decir que es una coincidencia que esto ayude a identificar este spam. Pero he descubierto al examinar las probabilidades de spam que hay muchos de estos accidentes, y tienen una tendencia asombrosa a empujar las cosas en la dirección correcta en lugar de la incorrecta. En este caso, no es del todo una coincidencia que la palabra "Republic" aparezca en correos de estafa nigerianos y en este spam. Hay toda una clase de proposiciones comerciales dudosas que involucran países menos desarrollados, y estos a su vez son más propensos a tener nombres que especifican explícitamente (porque no lo son) que son repúblicas.[3]

Por otro lado, "enter" es un error genuino. Aparece principalmente en instrucciones para darse de baja, pero aquí se usa de forma completamente inocente. Afortunadamente, el enfoque estadístico es bastante robusto y puede tolerar bastantes errores antes de que los resultados empiecen a desviarse.

Como comparación, aquí hay un ejemplo de ese raro pájaro, un spam que pasa los filtros. ¿Por qué? Porque por pura casualidad está cargado de palabras que aparecen en mi correo real: 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 Hay un par de buenas noticias aquí. Primero, este correo probablemente no pasaría los filtros de alguien que no se especializara en lenguajes de programación y tuviera un buen amigo llamado Morris. Para el usuario promedio, las cinco palabras principales aquí serían neutrales y no contribuirían a la probabilidad de spam.

Segundo, creo que el filtrado basado en pares de palabras (ver más abajo) podría bien capturar este: "cost effective", "setup fee", "money back" -- material bastante incriminatorio. Y por supuesto, si continuaran enviándome spam (o a una red de la que formaba parte), "Hostex" en sí mismo sería reconocido como un término de spam.

Finalmente, aquí hay un correo electrónico inocente. Sus quince palabras más interesantes son las siguientes: 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 mayoría de las palabras aquí indican que el correo es inocente. Hay dos palabras de mal augurio, "color" (a los spammers les encantan las fuentes de colores) y "California" (que aparece en testimonios y también en menús en formularios), pero no son suficientes para contrarrestar palabras obviamente inocentes como "continuation" y "example".

Es interesante que "describe" se considere tan completamente inocente. No ha aparecido en ninguno de mis 4000 spams. Los datos resultan estar llenos de tales sorpresas. Una de las cosas que aprendes cuando analizas textos de spam es cuán estrecho es el subconjunto del lenguaje en el que operan los spammers. Es ese hecho, junto con el vocabulario igualmente característico del correo de cualquier usuario individual, lo que hace que el filtrado bayesiano sea una buena apuesta.

Apéndice: Más Ideas

Una idea que aún no he probado es filtrar basándose en pares de palabras, o incluso tríos, en lugar de palabras individuales. Esto debería proporcionar una estimación mucho más precisa de la probabilidad. Por ejemplo, en mi base de datos actual, la palabra "offers" tiene una probabilidad de .96. Si basaras las probabilidades en pares de palabras, terminarías con "special offers" y "valuable offers" teniendo probabilidades de .99 y, digamos, "approach offers" (como en "this approach offers") teniendo una probabilidad de .1 o menos.

La razón por la que no he hecho esto es que el filtrado basado en palabras individuales ya funciona muy bien. Pero sí significa que hay margen para ajustar los filtros si el spam se vuelve más difícil de detectar. (Curiosamente, un filtro basado en pares de palabras sería en efecto un generador de texto de cadena de Markov ejecutándose a la inversa.)

Las características específicas del spam (por ejemplo, no ver la dirección del destinatario en el campo "to:") tienen, por supuesto, valor para reconocer el spam. Se pueden considerar en este algoritmo tratándolas como palabras virtuales. Probablemente haré esto en versiones futuras, al menos para un puñado de los indicadores de spam más flagrantes. Los filtros de spam que reconocen características tienen razón en muchos detalles; lo que les falta es una disciplina general para combinar la evidencia.

Reconocer características de no spam puede ser más importante que reconocer características de spam. Los falsos positivos son una preocupación tan grande que exigen medidas extraordinarias. Probablemente añadiré en versiones futuras un segundo nivel de prueba diseñado específicamente para evitar falsos positivos. Si un correo activa este segundo nivel de filtros, será aceptado incluso si su probabilidad de spam está por encima del umbral.

No espero que este segundo nivel de filtrado sea bayesiano. Inevitablemente será no solo ad hoc, sino basado en conjeturas, porque el número de falsos positivos no será lo suficientemente grande como para notar patrones. (Además, es mejor que un sistema de respaldo no dependa de la misma tecnología que el sistema principal.)

Otra cosa que puedo probar en el futuro es centrar atención adicional en partes específicas del correo electrónico. Por ejemplo, alrededor del 95% del spam actual incluye la url de un sitio que quieren que visites. (El 5% restante quiere que llames a un número de teléfono, respondas por correo electrónico o a una dirección de correo de EE. UU., o en algunos casos que compres ciertas acciones.) La url es en tales casos prácticamente suficiente por sí sola para determinar si el correo electrónico es spam.

Los nombres de dominio difieren del resto del texto en un correo electrónico (no alemán) en que a menudo consisten en varias palabras unidas. Aunque computacionalmente costoso en el caso general, podría valer la pena intentar descomponerlos. Si un filtro nunca ha visto el token "xxxporn" antes, tendrá una probabilidad de spam individual de .4, mientras que "xxx" y "porn" individualmente tienen probabilidades (en mi corpus) de .9889 y .99 respectivamente, y una probabilidad combinada de .9998.

Espero que la descomposición de nombres de dominio se vuelva más importante a medida que los spammers se vean gradualmente obligados a dejar de usar palabras incriminatorias en el texto de sus mensajes. (Una url con una dirección IP es, por supuesto, una señal extremadamente incriminatoria, excepto en el correo de algunos administradores de sistemas.)

Podría ser una buena idea tener una lista mantenida cooperativamente de urls promocionadas por spammers. Necesitaríamos una métrica de confianza del tipo estudiado por Raph Levien para evitar envíos maliciosos o incompetentes, pero si tuviéramos algo así, proporcionaría un impulso a cualquier software de filtrado. También sería una base conveniente para boicots.

Otra forma de probar urls dudosas sería enviar un rastreador para examinar el sitio antes de que el usuario mire el correo electrónico que lo menciona. Podrías usar un filtro bayesiano para calificar el sitio al igual que harías con un correo electrónico, y lo que se encontrara en el sitio podría incluirse en el cálculo de la probabilidad de que el correo electrónico sea spam. Una url que condujera a una redirección sería, por supuesto, especialmente sospechosa.

Un proyecto cooperativo que creo que sería realmente una buena idea sería acumular un corpus gigante de spam. Un corpus grande y limpio es la clave para que el filtrado bayesiano funcione bien. Los filtros bayesianos podrían usar el corpus como entrada. Pero un corpus así también sería útil para otros tipos de filtros, ya que podría usarse para probarlos.

Crear un corpus así plantea algunos problemas técnicos. Necesitaríamos métricas de confianza para evitar envíos maliciosos o incompetentes, por supuesto. También necesitaríamos formas de borrar información personal (no solo direcciones de destino y copias, sino también, por ejemplo, los argumentos de las urls de cancelación de suscripción, que a menudo codifican la dirección de destino) de los correos en el corpus. Si alguien quiere asumir este proyecto, sería algo bueno para el mundo.

Apéndice: Definiendo el Spam

Creo que hay un consenso general sobre lo que es el spam, pero sería útil tener una definición explícita. Tendremos que hacer esto si queremos establecer un corpus central de spam, o incluso para comparar las tasas de filtrado de spam de manera significativa.

Para empezar, el spam no es correo comercial no solicitado. Si alguien en mi vecindario se enterara de que estaba buscando una vieja Raleigh de tres velocidades en buen estado, y me enviara un correo electrónico ofreciéndome venderla, estaría encantado, y sin embargo este correo sería tanto comercial como no solicitado. La característica definitoria del spam (de hecho, su razón de ser) no es que no sea solicitado, sino que es automatizado.

Es meramente incidental, también, que el spam sea usualmente comercial. Si alguien empezara a enviar correos masivos para apoyar alguna causa política, por ejemplo, sería tanto spam como el correo que promociona un sitio pornográfico.

Propongo que definamos spam como correo automatizado no solicitado. Esta definición incluye, por lo tanto, algunos correos que muchas definiciones legales de spam no incluyen. Las definiciones legales de spam, influenciadas presumiblemente por los grupos de presión, tienden a excluir el correo enviado por empresas que tienen una "relación existente" con el destinatario. Pero comprar algo a una empresa, por ejemplo, no implica que hayas solicitado correos continuos de ellos. Si pido algo a una tienda en línea, y luego me envían un flujo de spam, sigue siendo spam.

Las empresas que envían spam a menudo te dan una forma de "darse de baja", o te piden que vayas a su sitio y cambies tus "preferencias de cuenta" si quieres dejar de recibir spam. Esto no es suficiente para que el correo deje de ser spam. No darse de baja no es lo mismo que darse de alta. A menos que el destinatario haya marcado explícitamente una casilla claramente etiquetada (cuyo valor predeterminado era no) pidiendo recibir el correo electrónico, entonces es spam.

En algunas relaciones comerciales, sí solicitas implícitamente ciertos tipos de correo. Cuando pides algo en línea, creo que solicitas implícitamente un recibo y una notificación cuando el pedido se envía. No me importa cuando Verisign me envía un correo advirtiéndome que un nombre de dominio está a punto de expirar (al menos, si son el registrador real para él). Pero cuando Verisign me envía un correo electrónico ofreciendo una Guía GRATUITA para Construir Mi Sitio Web de Comercio Electrónico, eso es spam.

Notas:

[1] Los ejemplos en este artículo se traducen a Common Lisp para, créase o no, una mayor accesibilidad. La aplicación descrita aquí es una que escribimos para probar un nuevo dialecto de Lisp llamado Arc que aún no ha sido lanzado.

[2] Actualmente la tarifa más baja parece ser de unos 200 dólares para enviar un millón de spams. Eso es muy barato, 1/50 de centavo por spam. Pero filtrar el 95% del spam, por ejemplo, aumentaría el costo de los spammers para llegar a una audiencia determinada en un factor de 20. Pocos pueden tener márgenes lo suficientemente grandes como para absorber eso.

[3] Como regla general, cuanto más calificadores haya antes del nombre de un país, más corruptos serán los gobernantes. Un país llamado La República Democrática Popular Socialista de X es probablemente el último lugar del mundo donde querrías vivir.

Gracias a Sarah Harlin por leer borradores de esto; Daniel Giffin (quien también está escribiendo el intérprete de producción de Arc) por varias buenas ideas sobre filtrado y por crear nuestra infraestructura de correo; Robert Morris, Trevor Blackwell y Erann Gat por muchas discusiones sobre spam; Raph Levien por consejos sobre métricas de confianza; y Chip Coldwell y Sam Steingold por consejos sobre estadísticas.

Encontrarás este ensayo y otros 14 en Hackers & Painters.

Más Información: