我正在创建一个 Python 应用程序,它允许我在某些行中使用变量。假设字符串和变量列表都是由用户直接提供的(在这种情况下,安全意味着防止 SSTI 等攻击),那么使用标准库对象string.Template
(https://docs.python.org/3/library/string.html#template-strings )是否安全?
换句话说,这样的代码是否安全:
import string
template_str = input("Введите строку: ")
variables = {}
while True:
name = input("Введите имя переменной (оставить пустым для отмены): ")
if not name.strip():
break
value = input("Введите значение переменной: ")
name, value = map(lambda s: s.strip(), [name, value])
if name in variables.keys():
print("Такая переменная уже существует")
else:
variables.update({name: value})
t = string.Template(template_str)
res = t.substitute(variables)
print(res)
注意:问题是如果用户可以控制字符串、变量名和值,使用过程是否安全,string.Template
而不是接下来字符串会发生什么。
虽然
string.Template
其本身是安全的,但如果在 Web 上下文中SSTI
使用 ( ) 的结果(例如,将其显示在页面上)而不进行转义,则用户可以通过变量值注入恶意软件。res
HTML
HTML/JavaScript
例如:
template_str = "Привет, $name!"
为变量name
输入一个值<script>alert('XSS')</script>
。res
将包含"Привет, <script>alert('XSS')</script>!"
。res
将其直接粘贴到 中HTML
,脚本将在其他用户的浏览器中运行。一种可能的解决方案是转义预期的输出
HTML
(例如使用html.escape()
标准库),或者使用自动执行此操作的框架/模板(但SSTI
如果您使用具有不安全设置的强大模板引擎,那么您将再次面临风险)。此外,理论上,用户可以提供非常大的模板字符串或大量的变量,这可能会导致过多的内存或 CPU 消耗。这种可能性比
SSTI
或要小XSS
,但仍然值得考虑输入大小的限制。