FlawOpen

flawopen.com/SSTI/Explicado

¿Qué es la inyección de plantillas del lado del servidor?

CWE-1336: Server-Side Template InjectionPágina de referencia
Respuesta breve

La inyección de plantillas del lado del servidor ocurre cuando una entrada no confiable se interpreta como código de plantilla en vez de pasarse como dato. El impacto depende del motor, su configuración y las capacidades expuestas: puede ir desde evaluar expresiones hasta ejecutar código en el servidor. No todos los casos permiten ejecución de código.

VULNERABLE — la entrada construye la plantilla
# Python / Jinja2
template = f"Hello {name}!"
return render_template_string(template)

# Input: {{ 7*7 }} renders as "49"
# This confirms expression evaluation;
# impact still depends on engine access.

// Java / Freemarker
String tpl = "Welcome " + userName;
new Template("t", tpl, cfg)
    .process(model, out);
CORREGIDO — la entrada es un dato
# The template is a fixed string the
# developer wrote. The user value is
# passed in as a variable.
return render_template(
    "greeting.html", name=name
)

# Or with a literal template string:
return render_template_string(
    "Hello {{ name }}!", name=name
)

// Java equivalent: template from file,
// user value in the model map.

La distinción clave

Todo motor de plantillas recibe dos entradas: la plantilla y los datos de contexto. La plantilla es un programa; los datos son los valores que lee. SSTI consiste en permitir que la entrada del usuario pase de la categoría de datos a la de código fuente de la plantilla.

Es el mismo error estructural que la inyección SQL, donde los datos se concatenan al texto de la consulta, y que Log4Shell, donde los datos llegaban a un evaluador de expresiones mediante un mensaje de registro. La solución sigue el mismo principio: mantener fijo el programa y pasar los valores no confiables por un canal de parámetros.

Cuándo el impacto puede incluir ejecución de código

Si el motor expone objetos o métodos potentes a la plantilla, un atacante podría alcanzar capacidades sensibles de la aplicación. La ejecución de código depende del motor, la versión, la configuración, el sandbox y los datos expuestos. Otros impactos posibles son la divulgación de información y el agotamiento de recursos. Trata el código de plantilla controlado por usuarios como lógica activa; no confíes únicamente en el sandbox sin limitar los objetos accesibles y los recursos de renderizado.

Cómo detectarla

{{7*7}} ${7*7} <%= 7*7 %> #{7*7}

Si la respuesta contiene 49 en vez del texto literal, la entrada se evalúa como sintaxis de plantilla. Estas pequeñas pruebas aritméticas ayudan a detectar la evaluación en un entorno de pruebas autorizado; la sintaxis varía y por sí sola no identifica el motor de forma fiable.

Preguntas frecuentes

¿Es lo mismo que XSS?

No. La inyección de plantillas del lado del cliente se ejecuta en el navegador de la víctima y puede ser una variante de XSS. SSTI se evalúa en el servidor, dentro del proceso de la aplicación. El impacto depende del motor y de las capacidades expuestas; algunas configuraciones permiten ejecutar código en el servidor, pero no ocurre automáticamente en todo SSTI.

¿El autoescape la evita?

No. El autoescape sanea los valores que se renderizan; no impide que un valor se analice como sintaxis de plantilla. Ayuda contra XSS en la salida, no contra la inyección en el código fuente de la plantilla.

¿Es seguro dejar que un administrador edite plantillas?

Trata el código de plantilla proporcionado por usuarios como lógica ejecutable y, por defecto, no lo proceses en el contexto principal de la aplicación. Si la función es necesaria, utiliza un motor diseñado para plantillas restringidas, expón solo datos inertes mínimos y aplica límites de CPU, memoria, tamaño de salida y tiempo. Un sandbox reduce el acceso, pero no es por sí solo una frontera de seguridad completa.

Referencias

Véase también SSTI: causa, impacto y corrección de template injection SSTI en FreeMarker y Velocity: seguridad de plantillas ¿Es seguro render_template_string() de Jinja2?