Dynaconf 由于 __@Jinja__ 解析器中的不安全模板求值,存在服务端模板注入(SSTI)漏洞。当安装了 jinja2 包时,Dynaconf 会在无沙箱环境下求值嵌入在配置值中的模板表达式。
如果攻击者能够影响配置源,例如:
.env 文件...他们就可以在主机系统上执行任意操作系统命令。此外,__@Format__ 解析器允许对象图遍历,这可能会暴露敏感的运行时对象和环境变量。
该漏洞的产生是因为 Dynaconf 的字符串解析器缺乏适当的安全边界。
__@Jinja__ 解析器__@Jinja__ 解析器使用完整的 Jinja2 求值来渲染模板。然而,渲染上下文未经过沙箱化,这允许攻击者访问 Python 的内部属性。通过使用 cycler 等对象,攻击者可以访问 Python 的全局变量并导入 os 模块。
示例攻击路径:
cycler → __init__ → __globals__ → os → popen()
这将导致任意命令执行。
__@Format__ 解析器__@Format__ 解析器使用内部对象执行 Python 字符串格式化。这允许攻击者遍历 Python 的对象图并访问敏感的运行时对象。
示例遍历:
{this.__class__.__init__.__globals__[os].environ}
这可能会暴露:
import os
from dynaconf import Dynaconf
# 恶意配置注入
os.environ["DYNACONF_RCE"] = "@jinja {{ cycler.__init__.__globals__.os.popen('id').read() }}"
settings = Dynaconf()
print("[!] 命令执行结果:")
print(settings.RCE)
成功利用该漏洞可允许攻击者:
由于配置值可能来自 CI/CD 流水线、容器编排系统或环境注入,该漏洞在真实部署中可能成为可远程利用的漏洞。
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
template = env.from_string("{{ config_value }}")
safe_value = template.render(config_value=user_input)
__@Format__ 的使用限制为可信值safe_value = "{name}".format(name=trusted_name)