
El 25 de septiembre llegó el reporte; la explotación andaba corriendo desde el 9 de julio. Lectura obligada si mantienes cualquier servicio que ejecute código subido por terceros.
La semana pasada LuaRocks.org, el repositorio oficial de paquetes de Lua, publicó el detalle completo de un incidente feo de verdad: una ejecución remota de código en su servidor, reportada vía CISA. Al investigar, descubrieron que la falla se había explotado varias veces entre el 9 de julio y el 20 de agosto. El atacante estuvo en la casa casi dos meses sin que nadie lo notara, y el reporte llegó un mes después del último ataque.
La falla: un sandbox que cargaba bytecode
El detalle técnico es corto pero brutal. Cuando subes un rockspec, el archivo que describe un paquete de Lua, el sitio lo ejecuta para leer campos como el nombre y la versión. Para hacerlo seguro, lo cargan con loadstring, lo corren con un ambiente vacío y limitan las instrucciones. Un sandbox razonable en teoría.
El problema: en Lua 5.1 y LuaJIT, loadstring acepta código fuente y también bytecode precompilado. Y el parser nunca le dijo «solo texto». Resultado: cualquiera con cuenta podía subir un «rockspec» que en realidad era bytecode. LuaJIT no verifica el bytecode en absoluto, así que un archivo armado a mano puede leer y escribir memoria del proceso, encontrar el estado real de Lua y llamar las funciones que el sandbox escondía. Chao sandbox, hola shell.
El arreglo fue pasarle el modo "t" (solo texto) a loadstring y rechazar de plano cualquier archivo que parta con el byte de firma del bytecode. Un parche de pocas líneas que estuvo ahí por años. La lección: un sandbox no vale nada si el parser de entrada acepta un formato que nunca auditaste. El ambiente vacío controla qué globales puede mirar el código, pero el bytecode no necesita ninguna, porque va directo a la memoria.
Lo que quedó expuesto
Como el usuario del servidor web podía llegar a admin, asumieron que el atacante leyó todo: usuarios, correos, hashes bcrypt, llaves de API, secretos de dos factores, tokens de GitHub, registros de sesión con IPs y credenciales de servicios externos. Todo revocado o eliminado. Los atacantes publicaron tres paquetes maliciosos con nombres absurdos, ya borrados de todos los espejos. Si instalaste alguno, trata esa máquina como comprometida.
El detalle que más me incomoda es el de los secretos de 2FA: el sitio guardaba las semillas TOTP de sus usuarios en el mismo servidor comprometido. Tu «segundo factor» vale lo que vale el servidor que guarda la semilla.
La parte buena: forense con respaldo externo
Lo rescatable es cómo probaron que nadie tocó los paquetes existentes. Todos los días LuaRocks copia cada rockspec y paquete publicado a un repositorio git público, fuera del servidor. Ese espejo les entregó un estado limpio del 8 de julio, previo al primer ataque, para comparar archivo por archivo y upload por upload. Sin ese respaldo externo, la conclusión de «no encontramos evidencia de manipulación» habría sido mucho más débil.
Yo hago lo mismo con mis VPS: los respaldos viven fuera del servidor, porque cuando algo se compromete, la primera máquina en la que no puedes confiar es la propia. Aquí el espejo diario no fue un backup decorativo: fue la evidencia forense que sostuvo todo el análisis. Esa es la lección práctica del caso, más que el detalle de loadstring.
La respuesta en general merece copiarse: servidor nuevo desde cero, todas las credenciales revocadas, sesiones cerradas, sitio en modo solo lectura durante la respuesta y un informe público con fechas exactas. Nada de silencio de tres líneas tres semanas después. Si todos los proyectos open source respondieran así, la cadena de suministro estaría bastante menos rota.
Si usas Lua: actualiza a LuaRocks 3.12 o más nuevo, crea tus llaves de API de nuevo y revisa tus paquetes en la página de auditoría si eres mantenedor. Y si no tocas Lua en la vida, quédate con las dos lecciones de fondo: respaldo externo para el día malo, y desconfianza absoluta de todo sandbox que acepte formatos binarios sin verificarlos.
Fuente: LuaRocks.org Security Incident, September 2026.
Fuente de inspiración: LuaRocks.org Security Incident, September 2026