Vulnerabilidad Server-side template injection
www.onlinetis.com
La vulnerabilidad de Server-side template injection (SSTI), o "inyección de plantillas del lado del servidor", ocurre cuando un atacante puede inyectar código malicioso directamente en una plantilla de un motor de renderizado del servidor. Esto le permite ejecutar comandos en el servidor, acceder a archivos del sistema de archivos, o robar información confidencial.
¿Cómo funciona?
Los motores de plantillas se utilizan en las aplicaciones web para generar páginas HTML dinámicamente. La aplicación toma un template (plantilla) que contiene marcadores de posición (por ejemplo, {{ user.name }}
) y los reemplaza con los datos reales antes de enviarlos al navegador del usuario. La vulnerabilidad surge cuando el atacante logra introducir código que no es solo texto, sino código de plantilla ejecutable.
Aplicación vulnerable: Una página web que muestra un mensaje de error personalizado que incluye la entrada del usuario.
return "Ocurrió un error. El nombre de usuario que ingresaste fue " + user_input
Código de plantilla vulnerable: Si esta entrada se renderiza directamente en una plantilla, un atacante podría enviar algo como
{{ 7 * 7 }}
. El motor de plantillas lo interpretaría como una expresión a evaluar, no como texto plano.Ataque: El atacante, en lugar de un simple nombre de usuario, introduce una cadena que contiene un comando de plantilla.
user_input = "{{ system('id') }}"
Resultado: El motor de plantillas interpreta
{{ system('id') }}
como una instrucción para ejecutar el comandoid
del sistema operativo. La aplicación devuelve el resultado del comando, exponiendo información del servidor.
¿Qué se puede lograr con SSTI?
Lectura de archivos: Un atacante puede leer archivos locales como
/etc/passwd
.Ejecución de código arbitrario: Permite ejecutar comandos del sistema operativo, lo que puede llevar al control total del servidor.
Obtención de información confidencial: Puede acceder a variables de entorno o credenciales almacenadas en la aplicación.
Prevención
La prevención se centra en la correcta gestión y validación de las entradas del usuario al interactuar con los motores de plantillas.
No renderizar entradas de usuario directamente: La mejor práctica es tratar toda la entrada del usuario como texto plano y no como código. Si la entrada debe ser parte de una plantilla, asegúrate de que se pase como una variable, no como parte de la sintaxis de la plantilla.
Sanitizar y validar: Si la aplicación requiere que los usuarios interactúen con plantillas, utiliza filtros de validación para eliminar caracteres y sintaxis que puedan ser interpretados como comandos de plantilla.
Utilizar "modos de caja de arena" (Sandbox): Algunos motores de plantillas ofrecen un modo de "sandbox" que limita la funcionalidad disponible para las plantillas, impidiendo la ejecución de comandos peligrosos.
La vulnerabilidad de Server-side template injection (SSTI) es un fallo de seguridad que permite a un atacante inyectar código malicioso en una plantilla de servidor para que se ejecute. La vulnerabilidad surge cuando la aplicación web no trata la entrada del usuario como texto plano, sino que la interpreta como parte del código de la plantilla.
¿Cómo funciona?
Los motores de plantillas como Twig, Jinja o Freemarker se utilizan para crear páginas HTML dinámicas. La aplicación toma una plantilla con marcadores de posición ({{ variable }}
) y los sustituye por datos reales.
Un ataque SSTI ocurre cuando un atacante logra que su entrada se evalúe dentro del contexto del motor de plantillas. Por ejemplo, en lugar de un nombre de usuario, el atacante puede inyectar una expresión matemática como {{ 7 * 7 }}
. Si el servidor devuelve 49
, el atacante sabe que la plantilla es vulnerable. A partir de ahí, puede escalar el ataque para ejecutar comandos del sistema operativo.
Ejemplo de ataque
Imagina que una aplicación web utiliza el siguiente código vulnerable:
name = request.args.get('name')
template = 'Hola ' + name + '!'
return render_template_string(template)
Si el atacante introduce {{ config.__class__.__init__.__globals__['os'].system('id') }}
, el motor de plantillas ejecutará el comando id
del sistema operativo, permitiéndole obtener información del servidor.
Prevención
La prevención se centra en la correcta gestión y validación de las entradas de usuario.
No renderizar entradas directamente: La mejor práctica es siempre pasar la entrada del usuario como una variable dentro del contexto de la plantilla, en lugar de concatenarla en la cadena de la plantilla.
Uso de sandboxes: Algunos motores de plantillas tienen modos de "caja de arena" que limitan la funcionalidad disponible, impidiendo la ejecución de comandos peligrosos.
Sanitizar y validar: Filtra y valida rigurosamente la entrada del usuario para eliminar cualquier carácter o sintaxis que pueda ser interpretado como código de plantilla.