Un truco nacido en la investigación de seguridad de IA acaba de aparecer en phishing corriente. Y la lección práctica no es para tu filtro de correo: es para cualquier sitio de tu código donde compares cadenas de texto.
Qué ha pasado
Los investigadores de Microsoft Noam Kochavi y Sarah Wolstencroft publicaron el jueves el análisis de una campaña de phishing que usaba ASCII smuggling: meter caracteres Unicode que no se dibujan en pantalla dentro de un texto que al humano le parece normal.
Los números, tal cual los cuentan ellos:
- La firma de detección salta a principios de febrero: unos 21.000 mensajes marcados el 8 de febrero y más de 1,3 millones al día siguiente.
- Fase intensa con volúmenes de entre 1 y 2,37 millones de mensajes por día laborable, con el máximo el 26 de febrero.
- A finales de marzo, alrededor de un 80 % menos por día laborable. Caída fuerte tras el 15 de mayo y algún pico pequeño hasta mediados de junio.
- Unos 150 dominios remitentes con temática financiera.
- Un patrón muy marcado: envío masivo de lunes a viernes, silencio el fin de semana.
Lo llamativo es para qué se usaban los caracteres invisibles. En la inyección indirecta de prompts, el atacante esconde instrucciones para un asistente en code points que el humano no ve pero el modelo sí decodifica. Aquí no había nada de eso:
«La sorpresa fue que no había ninguna instrucción oculta dirigida a un asistente de IA.»
En su lugar, insertaban espacios del bloque de tags de Unicode dentro de palabras del vocabulario financiero para partirlas: fun + U+E0020 + ding en lugar de «funding». El lector ve la palabra entera. Tu expresión regular, no.
Por qué importa
Porque el fallo no está en Unicode ni en el correo: está en la costumbre de comparar texto crudo con reglas literales. Y eso lo hacemos todos, mucho más de lo que recordamos.
Piensa dónde tienes comparaciones de cadenas que deciden algo en tu producto: listas de palabras prohibidas en un formulario, reglas antifraude sobre el concepto de una transferencia, deduplicación de registros, búsqueda interna, moderación de comentarios, validación de nombres de usuario o de dominio, detección de secretos antes de un commit, clasificación de facturas o de asuntos de correo. En todos esos sitios, un carácter que no se pinta en pantalla rompe la coincidencia sin que nadie note nada raro al mirar.
La recomendación de Microsoft es exactamente esa, y es la parte que me interesa: que las tuberías de normalización y de tokenización traten los caracteres tag de forma coherente, y que todo contenido que vaya a evaluarse por palabra clave, firma o regex pase primero por un paso que elimine o pliegue los code points invisibles.
Cómo lo montaría yo, concreto:
- Un único punto de normalización en la frontera de entrada. No normalices en cada comparación: eso garantiza que alguien se olvide en la tercera. Un solo helper por el que pasa todo lo que llega de fuera.
- Qué quita ese helper: el bloque de tags
U+E0000–U+E007F, los de ancho cero (U+200B–U+200D,U+FEFF), los controles de dirección bidi (U+202A–U+202E,U+2066–U+2069) y, según el caso, los selectores de variación. Encima, una normalización NFKC para unificar formas compatibles. - Guarda las dos versiones. Comparas contra la normalizada, muestras y almacenas la original. Si tiras el original, pierdes la prueba y rompes datos legítimos.
- Cuenta, no solo limpia. «Cuántos code points invisibles traía este texto» es un campo baratísimo de calcular y una señal buenísima: un asunto de correo normal trae cero.
- Que tu visor de logs los muestre. Si el atacante los esconde del ojo humano, tu panel de revisión también los esconde. Un modo que escape lo no imprimible en hexadecimal te ahorra una tarde de «pero si dice lo mismo».
Y hay dos lecturas más. La primera: si tu asistente ingiere correo, documentos o páginas web, ese mismo filtro es tu primera capa contra la inyección indirecta. Sale gratis, aprovéchalo. La segunda es organizativa: la técnica venía del mundo IA y ha aterrizado en el spam clásico. Si en tu casa las «cosas de IA» las mira una persona y el correo otra, este cruce se cae justo por la rendija. En Black Wings, que somos uno, al menos ese problema no lo tengo.
El otro regalo del informe es que el mejor indicador no era el contenido, sino la forma: volumen brutal de lunes a viernes, cero el fin de semana, dominios desechables recién estrenados y todos con temática financiera. Ese patrón lo puedes replicar en tu propio antifraude sin tocar una sola palabra clave.
Qué NO cambia
Seamos honestos con el tamaño de la noticia.
- No es una vulnerabilidad ni un exploit. Unicode hace lo que está documentado que hace. Es evasión de firmas, no ejecución de código.
- No hace el engaño más eficaz con la víctima. La persona lee lo mismo que leería sin el truco. Lo que se ataca es tu filtro, no su criterio.
- Normalizar no para el phishing. Solo devuelve al match literal la eficacia que ya tenía, que tampoco era mucha. El filtrado por palabras clave era una defensa flojita antes de esto y sigue siéndolo.
- No arrases el bloque de tags a ciegas. Las banderas de Inglaterra, Escocia y Gales se codifican con caracteres tag. Si tu producto muestra emoji, ese borrado no puede aplicarse al texto que vas a renderizar. Normaliza para comparar, no necesariamente para guardar y mostrar.
- Esto no resuelve la inyección de prompts. El problema de fondo es que el modelo no distingue datos de instrucciones; quitar invisibles cierra un canal de ocultación, no el ataque. El texto perfectamente visible sigue funcionando.
- No hay atribución ni sabemos si la campaña le salió rentable. Microsoft cuenta lo que vio en su telemetría, y ya está bien que lo cuente.
Si en tu producto hay comparaciones de texto que deciden algo —cobrar, bloquear, aprobar, deduplicar—, esta semana es buen momento para mirar por dónde entra ese texto. Cualquier duda me dices y lo vemos.
Un saludo, Vicente.
