flawopen.com/SSTI/Jinja2
Ist Jinja2s render_template_string() sicher?
Verwende render_template_string() nur, wenn der Anwendungscode den Template-String fest vorgibt. Werden nicht vertrauenswürdige Eingaben vor dem Parsen durch Jinja in diesen String eingesetzt, entsteht SSTI. In Flasks standardmäßig ungesandboxter Jinja-Umgebung kann dies abhängig von erreichbaren Objekten, Konfiguration und Anwendung bis zur Codeausführung führen; das geschieht nicht automatisch in jeder Bereitstellung.
# All four are the same bug render_template_string(f"Hi {name}") render_template_string("Hi " + name) render_template_string("Hi %s" % name) render_template_string("Hi {}".format(name)) # A very common real-world shape: @app.errorhandler(404) def not_found(e): return render_template_string( f"<h1>No such page: " f"{request.path}</h1>" ), 404 # The URL path is attacker-controlled.
# Template is a literal; the user value # arrives as a named context variable render_template_string( "Hi {{ name }}", name=name ) # Better still, a real template file render_template("greeting.html", name=name) # For the 404 case, no template # evaluation is needed at all: return render_template("404.html", path=request.path), 404
Warum angreiferkontrollierter Template-Quelltext relevant ist
Flask stellt Templates standardmäßig globale Anwendungsobjekte wie config, request und session bereit. Kontrolliert ein Angreifer den Template-Quelltext, wertet Jinja dessen Ausdrücke mit den in dieser Umgebung verfügbaren Objekten aus. Die Auswirkungen hängen von den Objekten und Fähigkeiten ab, die die Anwendung freigibt. Ein harmloser Rechenausdruck kann die Auswertung bestätigen, beweist allein aber weder Codeausführung noch den Zugriff auf bestimmte Daten.
Ein Template kann vertrauliche Werte offenlegen, wenn die Anwendung sie in den Kontext aufgenommen hat. Flask-config kann etwa SECRET_KEY oder Datenbankeinstellungen enthalten, doch Bereitstellungen unterscheiden sich. Lege keine Geheimnisse in für Templates sichtbare Daten und betrachte Output-Escaping nicht als Grenze gegen Template-Auswertung.
CVE-2024-56201 ist ein separater Fall
Diese Jinja-Compilerlücke ist von gewöhnlicher SSTI getrennt und keine Voraussetzung dafür: CVE-2024-56201 betrifft Jinja 3.0.0 bis 3.1.4, wenn ein Angreifer sowohl den Template-Inhalt als auch dessen Namen kontrollieren kann. Unter dieser Bedingung war beliebige Python-Codeausführung selbst mit Sandbox möglich. Jinja 3.1.5 behebt das Problem. Prüfe das Advisory und aktualisiere, wenn die Anwendung angreiferkontrollierte Templates oder Namen annimmt.
Wo das häufig vorkommt
Das Muster findet sich etwa in Fehlerseiten, die den angefragten Pfad ausgeben, Admin-Funktionen für E-Mail-Templates, mandantenspezifischer Gestaltung sowie Vorschau- und Debug-Endpunkten, die nicht öffentlich sein sollten.
Häufige Fragen
Nein. Autoescaping maskiert gerenderte Werte, um XSS in der Ausgabe zu verhindern. Es verhindert nicht, dass eine Nutzereingabe als Template-Quelltext kompiliert wird. Die Kontrollen greifen in unterschiedlichen Verarbeitungsschritten.
Jinja bietet SandboxedEnvironment für nutzerdefinierte Templates; die Dokumentation warnt jedoch, dass dies keine perfekte Sicherheit darstellt. Übergib nur benötigte Daten, vermeide Objekte mit Seiteneffekten und begrenze CPU, Speicher und Prozesse außerhalb der Template-Engine. Eine Sandbox macht die Interpolation nicht vertrauenswürdiger Eingaben vor dem Parsen nicht sicher.
Suche nach render_template_string und prüfe, ob das erste Argument ein fester, anwendungseigener String ist. Übergib Nutzerwerte als benannte Kontextvariablen oder verwende eine Template-Datei. Prüfe auch APIs, die Templates dynamisch kompilieren und deren Namen beeinflussen lassen.