4dim / Notas

Un contacto llamado =HYPERLINK: inyección de fórmulas en el CSV

El nombre de un contacto lo escribe un desconocido desde su WhatsApp. Si empieza por «=», Excel lo ejecuta como fórmula al abrir la exportación. Qué es la inyección CSV (CWE-1236), cómo se escapa, y por qué fue la primera prueba automática del repositorio.

El nombre lo escribe un desconocido

Si alguna vez descargas tu lista de clientes y la abres en Excel, esta nota te interesa. Cuenta cómo un desconocido puede meter una fórmula en esa hoja sin acercarse a tu computador, y cómo se evita.

En un CRM de WhatsApp, el nombre de un contacto no lo escribe el negocio. Lo escribe la persona que manda el primer mensaje, en el perfil de su propio WhatsApp. De ahí llega tal cual y se guarda tal cual. Puede ser «María Ruiz». Puede ser un emoji. Y puede ser =HYPERLINK("http://…";"Ver").

Mientras ese nombre vive en la pantalla del CRM, es un texto inofensivo. El problema empieza cuando el negocio exporta sus contactos a un archivo CSV y lo abre en Excel.

Lo que Excel hace con una celda que empieza por «=»

Excel interpreta como fórmula cualquier celda cuyo contenido empiece por =, +, - o @. LibreOffice y Google Sheets hacen algo parecido. Un CSV no marca qué es número, qué es texto y qué es fórmula: todo llega como texto, y la hoja de cálculo lo decide al abrirlo. Así que un contacto llamado =HYPERLINK(...) se convierte, en la hoja del negocio, en un enlace activo que apunta donde el desconocido quiso.

Esto se llama inyección de fórmulas, o inyección CSV. Tiene número propio en el catálogo público de debilidades de software: CWE-1236. Los usos conocidos empiezan por el enlace que lleva a quien lo pulsa a una página falsa. Llegan hasta fórmulas que, en versiones antiguas o con los avisos aceptados, intentan ejecutar comandos en el equipo de quien abre el archivo.

El camino es siempre el mismo. Un dato que controla un tercero. Exportado sin escapar. Abierto en un programa que ejecuta lo que empieza por «=».

El CSV es texto plano hasta que alguien lo abre. El ataque no está en el archivo: está en el programa que lo interpreta, y ese programa lo elige el negocio.

La corrección

Al escribir cada celda del CSV se mira con qué empieza. Si empieza por uno de los cuatro caracteres peligrosos, se le pone delante un apóstrofo ('). Las hojas de cálculo leen ese apóstrofo como «esto es texto» y muestran el valor sin ejecutarlo.

Las comillas dobles que haya dentro del valor se duplican, como manda el formato, para que nadie pueda cerrar la celda y abrir otra. Y todo esto se aplica a todas las columnas que vienen del exterior, no solo al nombre: el apellido, la empresa, la nota, cualquier campo que alguna vez haya escrito alguien de fuera.

No basta con mirar el primer carácter del valor. También hay que mirar lo que va después de un separador dentro de la misma celda, porque algunas hojas de cálculo evalúan tras un punto y coma o un tabulador. Ante la duda, el apóstrofo no hace daño.

Las primeras pruebas del repositorio

Esta corrección estrenó las pruebas automáticas del proyecto. Hasta ese día el repositorio no tenía ninguna. Desde entonces, cada vez que se ejecuta npm test se comprueban tres cosas: que un nombre que empieza por =, +, - o @ sale escapado, que las comillas se duplican, y que un nombre normal sale intacto. Con el ejecutor de pruebas que ya trae Node, sin instalar nada.

Lo contamos porque es representativo. La primera prueba de un proyecto casi nunca es la de la función más importante. Es la del fallo que asustó.

Dónde más aparece

  • Cualquier exportación a CSV o Excel de datos que escribieron usuarios: formularios de la web, comentarios, pedidos, registros de eventos.
  • Informes que se mandan por correo en un adjunto y se abren sin pensar.
  • Integraciones con Google Sheets que vuelcan datos de terceros.
  • El propio Excel al importar: la casilla «detectar tipos automáticamente» es la que convierte texto en fórmula.

Qué hacer entonces

  • Escapar con apóstrofo toda celda que empiece por =, +, - o @, en toda columna que venga de fuera.
  • Duplicar las comillas dobles dentro de los valores.
  • Escribir una prueba con el nombre =HYPERLINK(...) y no borrarla nunca.
  • Si se exporta a Excel nativo en vez de CSV, marcar las celdas como texto de forma explícita.
  • Preguntarle a cualquier herramienta que exporte tus contactos qué pasa con un contacto que se llame «=1+1». La respuesta correcta es que en la hoja aparece «=1+1».

Esta nota sale de nuestro trabajo en Software a medida.

← todas las notas