在服务器端将 python str.format 方法与用户提交的模板一起使用是否安全?

Is it safe to use python str.format method with user-submitted templates in server-side?

提问人:G. Bittencourt 提问时间:7/28/2023 更新时间:7/28/2023 访问量:70

问:

我正在从事一个项目,其中用户必须能够提交包含占位符的模板,以便稍后呈现以生成动态内容。

例如,用户可能会提交如下模板:

"${item.price} - {item.description} / {item.release_date}"

这将是在用实际值格式化之后。

为此目的使用模板引擎(如 Django 或 Jinja)需要进行大量验证和清理以防止 SSTI 和 XSS,所以我想知道我是否可以使用 python str.format 方法来创建一个更有限和更安全的替代方案,因为这种方法不能直接执行 python 代码(我相信)。

我的问题是:

在处理用户提交的模板时,使用 string.format 是否足够安全,或者它仍然容易受到注入攻击?
如果不是,有没有其他方法可以在 python 中实现“安全模板渲染”?

python 安全 xss 模板引擎

评论


答:

5赞 Brian61354270 7/28/2023 #1

不可以,与用户提供的格式字符串一起使用通常安全。str.format

在我的脑海中,我想出了这个玩具示例,说明如何通过精心构造的格式字符串轻松从服务器泄漏敏感信息。还可能存在其他攻击媒介。str.format

这种攻击仅依赖于攻击者知道(或猜测)提供给 的参数的类型。str.format

运行此代码将打印服务器上定义的所有环境变量:

import os

class Foo:
    def foo(self):
        pass

user_format = "{f.foo.__globals__[os].environ}"
print(user_format.format(f=Foo()))

具体到 Django,这个格式字符串将打印你的整个设置模块,包括你的数据库密码、签名密钥和各种其他可利用的信息:

user_format = "{f.foo.__globals__[sys].modules[myapp.settings].__dict__}"

评论

0赞 G. Bittencourt 7/28/2023
有趣。但是,假设我的渲染模块本身不直接导入“os”、“sys”或任何类似的模块(尽管它们是在项目中的其他脚本中导入的),仍然有可能利用这个漏洞吗?而且,如果我使用 运行此代码,限制全局变量怎么办?exec
1赞 user2357112 7/28/2023
@G.Bittencourt:此攻击不依赖于任何可以沙盒化的全局变量,也不依赖于任何渲染模块自己的导入。它只检查参数。execformat
0赞 Brian61354270 7/28/2023
@G.Bittencourt 至于第一部分,不需要直接导入,因为也可以遵循间接导入(例如,如果您在 的模块中导入,攻击可能会使用 - 导入的任何模块也是如此)。我不认为运行它会有所帮助,因为重要的是模块中的“全局变量”,而不是调用执行上下文中的全局变量。pathlibFoo__globals__[pathlib].osexecFoostr.format