Un motor de plantillas es como una máquina que te ayuda a construir páginas web de manera dinámica. Aquí está cómo funciona en términos simples:
Imagina que quieres regalarle una carta de cumpleaños a tu amigo. En lugar de hacer una desde cero puedes usar una plantilla con placeholders en el nombre, edad, etc.
Un motor de plantillas funciona similar:
- Plantilla: El motor usa una plantilla prediseñada con placeholders como
{{ name }}para el contenido dinámico. - Input del Usuario: El motor recibe el input del usuario (como nombre, edad o mensaje) y lo guarda en una variable.
- Combinación: El motor combina la plantilla con el input del usuario, reemplazando los placeholders con información real.
- Output: El motor genera una página web final dinámica con el input del usuario insertado.
Los motores de plantillas ofrecen varias funcionalidades que aceleran el proceso de desarrollo pero que también pueden introducir riesgos. La mayoría de motores permiten usar expresiones para cálculos o lógica simple en las plantillas. En el contexto de SSTI la habilidad de la plantilla de ejecutar código es lo que la hace vulnerable a los ataques.
Motores de Plantillas Comunes
Los motores de plantillas son una parte integral del desarrollo web moderno, permitiendo a los desarrolladores generar contenido HTML dinámico combinando plantillas con datos. Aquí algunos de los motores más usados:
- Jinja2: Altamente popular en aplicaciones Python, conocido por su expresividad y poderosas capacidades de renderizado.
- Twig: El motor de plantilla por defecto para Simfony en PHP. Ofrece un entorno robusto con configuración por defecto segura.
- Pug/Jade: Conocido por su sintaxis de plantilla HTML minimalista y limpia, popular entre desarrolladores Node.js.
Cómo Parsean y Procesan Inputs los Motores de Plantillas
Los motores de plantillas funcionan parseando archivos de plantillas, que contienen contenido estático mezclado con una sintaxis especial para el contenido dinámico. Cuando renderizamos una plantilla, el motor cambia las partes dinámicas con la información proporcionada en tiempo de ejecución. Por ejemplo:
from jinja2 import Template hello_template = Template("Hello, {{ name }}!") output = hello_template.render(name="World") print(output)
En este ejemplo, {{ name }} es un placeholder que se reemplaza con el valor "World" durante el renderizado.
Determinando el Motor de Plantillas
Los diferentes motores tienen distintas sintaxis y funcionalidades, haciéndolos vulnerables a SSTI de varias maneras. Aquí hay algunos ejemplos de sintaxis de plantillas vulnerables.
Jinja2/Twig
Jinja2 y Twig son similares en sintaxis y comportamiento, haciéndolos difícil de distinguir uno de otro sólo mediante respuestas de payload. Sin embargo, puedes detectar su presencia comprobando sus capacidades de manejo de expresiones. Por ejemplo, usando la máquina vulnerable, si usas el payload {{7*7}} en Twig obtendrás 49.

Sin embargo, si usas el mismo payload en Jinja2, el output será 7777777.

Jade/Pug
Pug, antes conocido como Jade, usa una sintaxis diferente para manejar expresiones, lo que puede ser explotado para identificar su uso. Pug/Jade evalúa las expresiones JavaScript en #{}. Por ejemplo, al usar el payload #{7*7} devolverá 49.

Al contrario que Jinja2 o Twig, Pug/Jade directamente permiten la ejecución de JavaScript en sus plantillas sin necesidad de delimitadores adicionales como {{}}. Por ejemplo:

