我想使用docxtpl的应用程序,让用户从自己的Word模板自动填充Word文档。用户可以在模板中的jinja2字段/标记中输入他们想要的任何代码。这引起了执行用户提交代码的安全问题。
Jinja2有它的SandboxedEnvironment
来评估不受信任的代码,它禁止访问不安全的方法和属性。Docxtpl使用jinja2。但是我在docxtpl文档中没有看到任何关于使用沙盒模式的内容。
这可能吗?如何?
参考:Jinja2 sandbox docs: https://jinja.palletsprojects.com/en/3.0.x/sandbox/
好吧,这是我想出的答案。
问:这可能吗?答:是的。
问:如何?答:通过将SandboxedEnvironment
作为jinja_env
的可选参数传入DocxTemplate
的渲染方法。
下面是一个工作示例:
docx_sandboxed.py
from docxtpl import DocxTemplate
from jinja2.sandbox import SandboxedEnvironment
class aClass():
def safe_method(self):
return "THIS IS safe_method"
def __str__(self):
return "This should raise a SecurityError exception"
doc = DocxTemplate("input_danger.docx")
A = aClass()
context = {
'var1': 'VAR1',
'object': A,
}
doc.render(context, jinja_env=SandboxedEnvironment())
doc.save("output.docx")
input_danger.docx
{{ var1 }}
{{ object.__str__() }}
如上面所示,使用input_danger.docx运行代码会引发jinja2.exceptions.SecurityError: access to attribute '__str__' of 'aClass' object is unsafe.
将第二个字段更改为{{ object.safe_method() }}
,它就工作了,产生:
output.docx
VAR1
THIS IS safe_method
我很高兴听到这种方法可能出现的任何问题/担忧。