FlawOpen

flawopen.com/Vulnerabilities/Server-Side Template Injection (SSTI)

Server-Side Template Injection (SSTI) : cause et correction de l’injection de templates

Impact depends on reachable template behavior CWE-1336 Template Engine Security
💡 Explication simple — données ou instructions de l’imprimante

Imaginez une entreprise qui imprime des lettres avec le modèle « Bonjour, {{ name }} ». La méthode sûre fournit à l’imprimante un modèle fixe et le nom du client comme donnée. La méthode risquée insère le texte du client dans les instructions du modèle avant l’impression. Si le moteur interprète ce texte comme de la syntaxe de template, il s’agit de Server-Side Template Injection. L’impact dépend du moteur, de sa configuration, des objets exposés et des privilèges du processus ; évaluer une expression ne signifie pas automatiquement exécuter des commandes système.

Cible : construction du code source de templates et rendu serveur avec des moteurs comme Jinja, Twig, FreeMarker et ERB.
Frontière vulnérable : une entrée non fiable est compilée ou analysée comme code source du template au lieu d’être transmise comme valeur à un template fiable.
Impact : évaluation d’expressions ; les conséquences dépendent des capacités du moteur, des objets exposés, du sandbox et des privilèges du processus.
Correction : garder le code source fiable et statique ; transmettre l’entrée non fiable uniquement comme donnée de contexte. Isoler les templates rédigés par les utilisateurs si cette fonction est nécessaire.

Concepts clés et termes du sous-système

Moteur de templates
Composant serveur, tel que Jinja ou Twig, qui analyse la syntaxe des templates et produit une sortie à partir d’un template et de données de contexte.
Injection dans le code source du template
Défaut où du texte externe est inséré dans le code source avant son analyse ; le moteur l’interprète alors comme une syntaxe plutôt que comme une donnée.
Données de contexte
Valeurs transmises séparément à un template fixe et fiable. Cette séparation empêche une valeur telle que {{ 7 * 7 }} d’être analysée à nouveau comme du code source.
CWE-1336
Neutralisation incorrecte d’éléments spéciaux utilisés par un moteur de templates. Cette catégorie décrit le traitement dangereux d’une entrée externe comme syntaxe de template.

Déroulement de l’attaque étape par étape

Step 1

Une entrée contrôlée par l’attaquant atteint un point de template

Un champ, une valeur de profil stockée ou une autre chaîne influencée de l’extérieur atteint le code qui crée ou compile un template. Le défaut porte sur la construction du code source, pas sur le simple rendu d’une valeur.

Step 2

L’application mélange données et instructions du template

L’application interpole la chaîne non fiable dans le code source du template (par exemple une f-string transmise à render_template_string) au lieu d’utiliser un template statique et une valeur de contexte séparée.

Step 3

Le moteur analyse le code combiné

Le moteur interprète les expressions selon son langage et sa configuration. Une expression arithmétique inoffensive peut montrer qu’une évaluation a lieu ; cela ne prouve pas à lui seul un accès aux fichiers, aux secrets ou aux commandes système.

Step 4

L’impact dépend du moteur et du déploiement

Les conséquences dépendent des objets et fonctions accessibles, du sandbox, des restrictions du moteur et des privilèges du processus web. Une RCE est possible dans certaines configurations, mais n’est pas automatique pour toute SSTI.

Mécanisme et cause racine

Une SSTI se produit lorsqu’une application incorpore du texte influencé de l’extérieur au programme du template avant son analyse. Avec Flask/Jinja, le modèle vulnérable construit une nouvelle chaîne source à partir des données de la requête et la transmet à render_template_string() ; l’échappement HTML protège la sortie et ne transforme pas un code source non fiable en donnée. La correction charge un template fixe et transmet la valeur séparément dans le contexte. Si les utilisateurs doivent rédiger des templates, exposez un modèle de données minimal et effectuez le rendu dans un worker isolé avec des limites de ressources. Le sandbox est une défense en profondeur, pas une raison d’exposer des secrets ou des objets puissants.

flask_app.py (Modèle vulnérable)Vulnérable
# VULNERABLE: request data becomes template source before parsing.
from flask import Flask, request, render_template_string
app = Flask(__name__)

@app.route("/greet")
def greet():
    name = request.args.get("name", "Guest")
    # A value such as {{ 7 * 7 }} is interpreted by the template engine.
    source = f"<h1>Welcome, {name}!</h1>"
    return render_template_string(source)
flask_app.py (Protégé)Protégé
# HARDENED: fixed template source; request data stays a context value.
from flask import Flask, request, render_template
app = Flask(__name__)

@app.route("/greet")
def greet():
    name = request.args.get("name", "Guest")
    return render_template("greet.html", name=name)

# templates/greet.html is trusted, static source:
# <h1>Welcome, {{ name }}!</h1>

Séquence d’attaque et exemple conceptuel

Règles de prévention et de protection technique

Sources principales et sujets de sécurité associés :Répertoire complet de sécurité →
CWE-1336 : injection dans un moteur de templates → OWASP WSTG : Server-Side Template Injection → Jinja : sandbox et sécurité → API Jinja : templates et loaders → Flask : rendu des templates →