Tácticas de spam

El truco de los caracteres invisibles: por qué tu filtro de Twitter no detecta el spam

Una respuesta de spam en X junto a su texto en bruto, lleno de caracteres de ancho cero
Respuesta rápida
  • Las respuestas de spam rellenan cada carácter con caracteres de ancho cero invisibles. En pantalla el texto se ve normal; como cadena, es irreconocible.
  • Ninguna palabra clave ni regex puede coincidir, porque la frase que buscas ya no es contigua.
  • La solución tiene dos partes: quitar los caracteres invisibles antes de comparar, y por separado marcar las publicaciones que son sobre todo relleno invisible.
  • X Spam Blocker hace las dos cosas, y la segunda regla sigue funcionando cuando el spam reescribe su guion.

Esta vale la pena entenderla aunque nunca instales nada, porque explica una frustración que casi todo el que intentó filtrar spam en X ha tenido: una respuesta que es spam inequívoco, que a la vista contiene la frase exacta de tu lista de filtros, y que tu filtro no atrapa. La publicación no te miente. Tu filtro está mirando una cadena distinta de la que puedes ver.

El síntoma

Digamos que tienes looks better than me en tu lista de palabras clave, y llega una respuesta que se lee, con toda claridad, nobody looks better than me. Tu filtro no se dispara. Revisas errores de tipeo. Revisas que el escaneo esté activo. Copias el texto de la publicación y lo pegas en tu lista de filtros, y eso tampoco funciona — de hecho, ahora no coincide nada.

En ese punto la explicación es casi siempre el relleno. El texto visible y el texto subyacente no son la misma cosa, y cuando copiaste la publicación copiaste el relleno junto con ella.

Cómo funciona el truco

Unicode tiene una serie de caracteres que son invisibles a propósito. Existen para hacer trabajos distintos de ser vistos: unir dos emoji en uno, decirle a una escritura cómo deben conectarse las letras vecinas, marcar un cambio de dirección del texto. Se dibujan como nada, no ocupan ancho y sobreviven al copiar y pegar.

Así que quien hace spam inserta uno entre cada carácter del mensaje. Una frase de ocho caracteres se vuelve una cadena de veinticinco, de los cuales diecisiete son invisibles. Para quien lee, son ocho caracteres. Para un filtro, es una secuencia en la que nunca hay dos letras de tu palabra clave juntas.

VisibleCaracteres reales
Lo que ve quien lee8—
Lo que lee el filtro825, 17 de ellos invisibles
¿Contiene tu palabra clave?SíNo

A quien hace spam no le cuesta nada — es un buscar y reemplazar en el guion que publica las respuestas — y derrota de un golpe a todo filtro ingenuo.

Los caracteres involucrados

En muestras tomadas de spam de respuestas en vivo, el relleno es casi siempre uno de estos tres, rotados para no verse mecánicos:

Punto de códigoNombreTrabajo legítimo
U+200CZero-width non-joinerEvita que las letras se unan en persa, árabe y devanagari
U+200DZero-width joinerUne emoji en un solo glifo, por ejemplo una familia o una profesión
U+2060Word joinerEvita un salto de línea sin agregar un espacio

Hay otros de la misma familia — la marca de orden de bytes U+FEFF, las marcas de dirección U+200E y U+200F, el guion suave U+00AD, el separador de vocales mongol U+180E, las anulaciones bidireccionales del rango U+202A–U+202E. Un filtro a fondo tiene que contar con todos, porque el que se le escape es el que se usa después.

Míralo tú mismo en veinte segundos

No necesitas ninguna herramienta para esto. Abre una respuesta de spam, selecciona su texto, cópialo y pégalo en algún lugar que te diga el largo — una consola del navegador es lo más fácil:

const s = `paste the copied reply here`
console.log(s.length)
console.log((s.match(/[­᠎​-‏⁠-⁤]/g) || []).length)

Una frase normal devuelve un segundo número de cero. El spam relleno devuelve algo cercano al primer número. En un hilo de muestra, cuatro respuestas de once llevaban de 52 a 67 caracteres invisibles cada una — alrededor del 80 % de la cadena cruda — mientras que las otras siete midieron exactamente cero. No hay una zona gris en el medio; eso es lo que lo hace detectable.

Por qué todo filtro de texto falla con esto

Vale la pena ser precisos, porque el fallo no es de ningún filtro en particular. Tres defensas se rompen a la vez:

  • Palabras clave exactas. Muertas de inmediato. La subcadena no existe.
  • Regex "sueltos" que permiten un hueco entre caracteres — algo como b.{0,3}e.{0,3}t — sobreviven a un carácter de relleno por hueco y mueren a los seis.
  • Palabras clave copiadas y pegadas. Copiar la frase del spam trae su relleno, así que tu nueva palabra clave solo coincide con esa publicación, con esa disposición exacta de rellenos.

Hay un cuarto fallo fácil de pasar por alto. En JavaScript, un cuantificador como .{0,3} cuenta unidades de código UTF-16, no caracteres — y un emoji son dos unidades de código. Así que un regex suelto escrito para tolerar tres caracteres de hueco en realidad tolera un emoji, y por eso separar una palabra con emoji también le gana a un patrón suelto.

Solución uno: quitar los caracteres antes de comparar

El lugar correcto para resolver esto es antes de que corra cualquier regla. X Spam Blocker arma una copia limpia del texto que está por comparar: se quitan los caracteres invisibles y luego se aplica la normalización Unicode NFKC para que las letras de ancho completo, circuladas y en subíndice o superíndice vuelvan a ser letras simples. Después arma una tercera copia, más compacta, con todos los espacios, la puntuación y los emoji eliminados, dejando solo letras y dígitos.

Las reglas se prueban contra las tres, y tus palabras clave se normalizan de la misma forma. Eso tiene tres consecuencias útiles:

  • Tu lista actual de palabras clave empieza a funcionar con el spam relleno sin que cambies nada.
  • Una palabra clave que copiaste de una respuesta de spam, relleno incluido, sigue funcionando como filtro.
  • Separar una palabra con emoji — la variante que le gana a los regex sueltos — lo resuelve la copia compacta, que descarta los emoji por completo.

Nada de la página se modifica. La limpieza solo se aplica a la copia usada para comparar.

Solución dos: detectar la forma, no las palabras

Quitar caracteres arregla el spam de hoy. No arregla el del mes que viene, porque el texto va a cambiar y tu lista de palabras clave no va a haberlo alcanzado. Así que hay una segunda regla, independiente, que ignora el texto por completo:

Si al menos el 30 % de los caracteres de una publicación son invisibles sospechosos, y hay al menos 6 de ellos, y la publicación tiene al menos 8 caracteres — márcala. No hace falta palabra clave.

Esa es toda la regla, y su valor está en que el relleno invisible pesado es en sí mismo la señal de spam. Nadie escribe una publicación normal que sea un tercio de caracteres invisibles. La brecha medida es enorme: las respuestas de spam de la muestra marcaron del 53 % al 60 % en el conjunto reducido de caracteres, y las publicaciones normales marcaron cero. Un umbral del 30 % queda en el medio de una banda vacía muy ancha.

En el panel es el interruptor Detectar también publicaciones rellenadas con caracteres invisibles, activo por defecto. Cuando se dispara, el candidato y la entrada del registro dicen "Ofuscación con caracteres invisibles" con el porcentaje medido, así puedes distinguirlo de una de tus propias palabras clave. Las coincidencias de palabras clave tienen prioridad, así que cuando ambas se dispararían obtienes la palabra concreta — que es más útil cuando estás depurando una regla.

El problema de los emoji, y por qué la regla es más estrecha de lo que parece

Esta es la parte que hace o deshace una regla como esta. El unidor de ancho cero U+200D no es solo una herramienta de spam: es el pegamento de los emoji compuestos. Un emoji de familia son tres personas visibles unidas por dos caracteres U+200D. Mídelo de forma ingenua y obtienes un 40 % de caracteres invisibles: un falso positivo en la publicación más inocente que se pueda imaginar.

Por eso la regla de detección usa un conjunto de caracteres deliberadamente más estrecho que el de la limpieza. Tres categorías enteras quedan fuera de lo que cuenta como evidencia:

  • U+200D, el unidor de ancho cero — porque los emoji compuestos están llenos de él.
  • U+FE00–U+FE0F, los selectores de variación — el carácter invisible que hace que ❤️ se dibuje a color.
  • U+E0020–U+E007F, los caracteres de etiqueta — usados por banderas de subdivisión como 🏴󠁧󠁢󠁥󠁮󠁧󠁿.

Quitar esos tres deja al spam de relleno todavía en los cincuenta altos, porque U+200C y U+2060 solos bastan para condenarlo. Verificado contra secuencias de emoji de familia, corazones de color, la bandera del arcoíris, emoji de profesiones, banderas de subdivisión, texto persa que usa U+200C como ortografía real, y publicaciones muy cortas rellenadas a propósito: en todos esos casos la medida es 0,0 %.

Ese es el intercambio que vale la pena copiar si armas algo parecido: una regla de limpieza puede ser glotona, porque una limpieza de más no cuesta nada. Una regla de detección tiene que ser tacaña, porque una marca falsa te cuesta una cuenta real.

Los trucos relacionados, ya que estás aquí

El relleno invisible es la evasión más común, pero no la única, y la misma normalización cubre a la mayor parte de la familia:

  • Letras de ancho completo y decoradas. Texto Fullwidth, letras circuladas, negrita matemática — todo vuelve a letras simples bajo NFKC.
  • Emoji como separadores. Una palabra partida con emoji entre los caracteres, que la copia compacta resuelve borrándolos.
  • Homoglifos. El cirílico а por la a latina, la ο griega por la o. NFKC no los pliega — son letras de verdad distintas — así que siguen siendo un hueco real. Una sustitución de homoglifos también es, útilmente, algo a lo que la regla de forma se puede apuntar en el futuro.

Para los filtros que se apoyan en todo esto, mira bloquear cuentas de Twitter por palabra clave o regex, o las listas listas para usar en bloquear estafas cripto y bots de spam en X.

Preguntas frecuentes

¿Qué son los caracteres de ancho cero?

Caracteres Unicode reales que no ocupan espacio al dibujarse. Existen por razones legítimas — unir emoji, controlar cómo se conectan las letras persas y devanagari, marcar la dirección del texto — pero como son invisibles y se copian y pegan limpios, también son una forma cómoda de romper un filtro de texto.

¿X puede detectar esto por su cuenta?

X claramente filtra una parte, porque el mismo spam a menudo se termina quitando. Pero los caracteres invisibles son legítimos en suficientes contextos como para que una plataforma no pueda simplemente prohibirlos, y el spam de respuestas que sobrevive lo suficiente para ser visto ya hizo su trabajo. Un filtro de tu lado no tiene que esperar a nadie.

¿Quitar los caracteres invisibles rompe las publicaciones normales?

No de una forma que notarías, porque la limpieza solo ocurre en la copia usada para comparar: nada de la página se altera. La detección es más estricta: el conjunto de caracteres de la regla de relleno oculto deja fuera a propósito los unidores de emoji y los selectores de variación, así que una publicación llena de emoji nunca se marca por eso.

¿Qué proporción cuenta como ofuscada?

Que el 30 % o más de la cadena sean caracteres invisibles sospechosos, con al menos seis de ellos, y que el texto tenga al menos ocho caracteres. Las respuestas de spam medidas llegan al 53–60 %. Las publicaciones normales, incluidas las llenas de emoji y banderas, miden cero.

¿Por qué el registro dice un porcentaje en lugar de una palabra clave?

Porque ninguna palabra clave coincidió: la publicación se marcó por su forma. El registro muestra "Ofuscación con caracteres invisibles" con la proporción medida, lo que te dice que la regla que se disparó fue la de la forma y no una de las tuyas.

Bloquea cuentas de spam en X en masa, después de confirmar

Extensión gratuita de Chrome. Sin cuenta, sin servidor, sin rastreo.

Agregar a Chrome
Primeros pasos

Cómo bloquear cuentas en masa en Twitter (X) en 2026

El flujo completo para un bloqueo masivo en X: escribe tus filtros, revisa la cronología, mira la lista de candidatos y procesa cincuenta cuentas a un ritmo que no dispare los límites de X. Incluye qué hacer ante un 429.

9 min de lectura