Resumen
Redis es un software que almacena datos en memoria RAM con muy baja latencia y permite la ejecución de scripts Lua a través de los comandos EVAL y EVALSHA.
Durante la ejecución de estos scripts, Redis gestiona incorrectamente referencias de memoria asociadas al garbage collector de Lua, pudiendo acceder a memoria ya liberada.
Esta condición puede ser aprovechada por un atacante autenticado para ejecutar código arbitrario y derivar en una ejecución remota de código (RCE).
Contexto del software
Generalmente el uso a esta aplicación es dado como una capa intermedia para evitar consultas continuas a la base de datos del servidor. Suele emplearse para manejar autenticación, configuraciones de usuario y otros datos temporales.
En despliegues típicos, no se accede a la aplicación de manera directa por usuarios finales, sino que forma parte del servidor de la aplicación (backend) y es utilizado por otros servicios internos. Por eso es que Redis suele ejecutarse dentro del mismo servidor o red interna que la lógica principal de la aplicación.
Una vulnerabilidad RCE en Redis puede resultar muy peligrosa en un contexto como este, porque permite a un atacante ejecutar código directamente en el servidor. Con lograr este acceso, no solo estamos hablando de que pueda manipular los datos que gestiona Redis, sino también comprometer el entorno del servidor y afectar a otros servicios o infraestructura relacionada.
Qué falla y por qué
La vulnerabilidad surge durante la ejecución de ciertos scripts Lua en Redis a través de los comandos EVAL y EVALSHA. Durante ese flujo, entra en juego el garbage collector de Lua, que básicamente se encarga de liberar objetos en memoria que ya no se consideran en uso.
El núcleo del problema esta en que Redis no gestiona correctamente el ciclo de vida de objetos que se comparten con Lua. El garbage collector en ciertos casos puede liberar memoria que Redis todavía tiene como referencia internamente para usar, y eso provoca que la aplicación continúe operando sobre memoria que ya no es válida.
Esto rompe el modelo de confianza, ya que termina aplicando lógica sobre datos que pueden ser controlados por un atacante. El resultado es un fallo que se convierte en una vulnerabilidad de seguridad crítica ya que permite la ejecución de código remoto (RCE).
Impacto realista
Hay que tener bien en claro el posible escenario de explotación. Ésta vulnerabilidad no va a funcionar como un vector inicial desde internet porque requiere acceso previo a Redis y a la capacidad de poder ejecutar scripts Lua mediante dichos comandos. Siguiendo configuraciones de seguridad estándar, el software debería estar funcionando solo en red interna.
Hay que recalcar de todas formas que el impacto del CVE es crítico en escenarios de una mala configuración u obtención de acceso al servidor.
Si Redis queda expuesto por error a internet, el servicio se convierte en un vector de ataque directo. En un escenario como este, la posibilidad de ejecutar código a través de la aplicación permite comprometer el funcionamiento esperado y agravar el impacto del incidente.
Detección y defensa
Para saber hacia donde debemos mirar podríamos tener en cuenta primero el uso de comandos Lua EVAL o EVALSHA y especialmente prestar atención en entornos donde Redis no ejecuta scripts habitualmente. Otra cuestión a tener en cuenta es fijarse en el rendimiento del proceso. Si surgen picos de consumo en CPU o cae el rendimiento o cualquier otra cosa que genere ruido en el sistema consistente con el código del backend.
La principal forma de mitigar es actualizar. Si todavía no está hecho, también se recomienda restringir el acceso de Redis a la red interna y chequear credenciales. Otra cuestión importante al momento de protegerse es tener en cuenta la superficie de ataque: si mi entorno no precisa ejecución de scripts Lua, entonces los deshabilito. De ésta manera minimizo el riesgo a que se explote una vulnerabilidad.