Inyección de Plantillas del Lado del Servidor (SSTI)

cuando el render te juega en contra

SSTI ocurre cuando una aplicación mete valores que vienen del usuario directamente en una plantilla sin controlarlos ni filtrarlos. Eso puede acabar en ejecución remota de código si el motor de plantillas lo permite y el dev no cortó lo que tocaba.

¿Dónde empieza la liada?

Algo básico:

Hola {{nombre}}

Si metes {{7*7}} y te sale Hola 49, hay SSTI. Pero eso es solo el principio.

Subiendo de nivel: explorando el entorno

En motores como Jinja2, podrías meter cosas como:

{{ config }}

O peor:

{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('ls').read() }}

Y si eso te saca cosas del sistema, ya estamos hablando de RCE directo. Ahi la fiesta empieza de verdad.

Plantillas: qué hacen y por qué se rompen

Una template debería recibir datos ya validados, tipo:

"Bienvenido {{usuario}}"

Pero si al final el usuario puede modificar la propia lógica de la plantilla (y no solo el valor), puede colarse lógica, llamadas a funciones, e incluso escapes del sandbox.

Motores que han petado feo

Explotación típica

1. Mandas un input con algo que sabes que se ejecuta, tipo {{7*8}}.
2. Si ves que sale 56 en vez de lo que escribiste, ya sabes que evalúa.
3. Buscas objetos accesibles: {{ self }}, {{ config }}, {{ ''.__class__.__mro__ }}...
4. Intentas llegar a funciones tipo os.system o popen() para ejecutar comandos.

Bypasses y evasiones

Hay filtros tontos tipo bloquear { o }}, pero los motores suelen permitir notación alternativa:

Prevención real

← Volver al blog