Dynaconf is vulnerable to Server-Side Template Injection (SSTI) due to unsafe template evaluation in the @jinja resolver. When the jinja2 package is installed, Dynaconf evaluates template expressions embedded in configuration values without a sandboxed environment.
If an attacker can influence configuration sources such as: environment variables .env files container environment configuration CI/CD secrets they can execute arbitrary OS commands on the host system. In addition, the @format resolver allows object graph traversal, which may expose sensitive runtime objects and environment variables.
The vulnerability arises because Dynaconf's string resolvers lack proper security boundaries.
Example attack path cycler → init → globals → os → popen() This leads to arbitrary command execution.
import os
from dynaconf import Dynaconf
# Malicious configuration injection
os.environ["DYNACONF_RCE"] = "@jinja {{ cycler.__init__.__globals__.os.popen('id').read() }}"
settings = Dynaconf()
print("[!] Command Execution Result:")
print(settings.RCE)
Successful exploitation allows attackers to: - Execute arbitrary OS commands on the host system - Access sensitive environment variables - Compromise application secrets - Fully compromise the running application process Because configuration values may originate from CI/CD pipelines, container orchestration systems, or environment injection, this vulnerability can become remotely exploitable in real-world deployments.
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
template = env.from_string("{{ config_value }}")
safe_value = template.render(config_value=user_input
2. Restrict @format usage to trusted values
safevalue = "{name}".format(name=trustedname)
```{
"cwe_ids": [
"CWE-1336",
"CWE-94"
],
"severity": "HIGH",
"nvd_published_at": "2026-03-20T21:17:15Z",
"github_reviewed": true,
"github_reviewed_at": "2026-03-18T20:08:06Z"
}