提问人:G. Bittencourt 提问时间:7/28/2023 更新时间:7/28/2023 访问量:70
在服务器端将 python str.format 方法与用户提交的模板一起使用是否安全?
Is it safe to use python str.format method with user-submitted templates in server-side?
问:
我正在从事一个项目,其中用户必须能够提交包含占位符的模板,以便稍后呈现以生成动态内容。
例如,用户可能会提交如下模板:
"${item.price} - {item.description} / {item.release_date}"
这将是在用实际值格式化之后。
为此目的使用模板引擎(如 Django 或 Jinja)需要进行大量验证和清理以防止 SSTI 和 XSS,所以我想知道我是否可以使用 python str.format 方法来创建一个更有限和更安全的替代方案,因为这种方法不能直接执行 python 代码(我相信)。
我的问题是:
在处理用户提交的模板时,使用 string.format 是否足够安全,或者它仍然容易受到注入攻击?
如果不是,有没有其他方法可以在 python 中实现“安全模板渲染”?
答:
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:此攻击不依赖于任何可以沙盒化的全局变量,也不依赖于任何渲染模块自己的导入。它只检查参数。exec
format
0赞
Brian61354270
7/28/2023
@G.Bittencourt 至于第一部分,不需要直接导入,因为也可以遵循间接导入(例如,如果您在 的模块中导入,攻击可能会使用 - 导入的任何模块也是如此)。我不认为运行它会有所帮助,因为重要的是模块中的“全局变量”,而不是调用执行上下文中的全局变量。pathlib
Foo
__globals__[pathlib].os
exec
Foo
str.format
评论