在Django中为富文本字段使用安全过滤器

14 投票
4 回答
13988 浏览
提问于 2025-04-15 14:16

我在使用TinyMCE编辑器来处理Django表单中的文本框。

为了把富文本展示给用户,我必须在Django模板中使用“safe”过滤器,这样才能让HTML富文本在浏览器中正常显示。

但是,如果用户的浏览器禁用了JavaScript,TinyMCE就无法加载,这样用户可能会在文本框中输入一些像<script>这样的标签,或者其他的跨站脚本(XSS)代码。这些HTML内容在展示给用户时就不安全了。

我该如何处理这些不安全的HTML文本呢?

4 个回答

6

你可以使用模板过滤器 "removetags" 来移除 'script' 标签。

不过要注意,removetags 在 Django 2.0 中已经被移除了。以下是文档中的弃用通知:

自 1.8 版本起已弃用: removetags 不能保证输出的 HTML 是安全的,因此由于安全问题被弃用了。建议使用 bleach 作为替代。

14

你提到的关于原始HTML的担忧是对的,但不仅仅是针对那些禁用JavaScript的浏览器。当我们考虑服务器的安全性时,不能只关注浏览器里的操作,而是要看服务器接受了什么,以及这些内容会发生什么。你的服务器接受HTML并在页面上显示,这样做是不安全的。

TinyMce对HTML的处理给人一种虚假的安全感:服务器信任它所接受的内容,但这其实是不应该的。

解决这个问题的方法是,在HTML到达服务器时进行处理,去掉那些危险的部分。这是一个复杂的问题。你可以查看一下XSS备忘单,了解一下可能导致问题的各种输入。

lxml有一个清理HTML的功能:http://lxml.de/lxmlhtml.html#cleaning-up-html,不过我自己没用过,所以不能保证它的效果。

15

可以使用 django-bleach。这个工具给你提供了一个叫做 bleach 的模板过滤器,它可以帮你过滤掉不想要的标签,只保留你想要的标签:

{% load bleach_tags %}
{{ mymodel.my_html_field|bleach }}

关键是要设置编辑器,让它生成的标签和你在 bleach 设置中允许的标签一致。

下面是我设置的 bleach 示例:

# Which HTML tags are allowed
BLEACH_ALLOWED_TAGS = ['p', 'h3', 'h4', 'em', 'strong', 'a', 'ul', 'ol', 'li', 'blockquote']
# Which HTML attributes are allowed
BLEACH_ALLOWED_ATTRIBUTES = ['href', 'title', 'name']
BLEACH_STRIP_TAGS = True

然后你可以配置 TinyMCE(或者你使用的其他所见即所得编辑器),只显示那些可以创建允许标签的按钮。

撰写回答