Django安全处理用户输入。html.strip_tags足够吗,还是应该使用bleach?

0 投票
2 回答
2043 浏览
提问于 2025-04-18 14:22

我在一个小论坛上接受用户输入,处理用户输入的步骤如下:

  • 首先,我使用“html.strip_tags”这个函数,它来自 django.utils.html,对用户的输入进行清理。

  • 然后,把清理后的内容保存到数据库里,使用的是Postgre数据库。

  • 接着,我查询这些文本,并用正则表达式把换行符(\n)替换成
    ,同时显示用户输入的空格。

  • 然后,我用{{text|safe}}来显示这些文本(如果不标记为安全,段落之间的空格就不会显示出来,只会显示
    标签)。

  • 最后,我在文本上使用一些jQuery插件,比如 Autolinker.js 来检测并“链接化”超链接,还有 trunk8 来控制文本的长度。

因为我使用了{{text|safe}},所以我有点担心恶意输入,使用html.strip_tags是否足够安全呢?

关于strip_tags的文档写道:

“尝试从字符串中移除任何看起来像HTML标签的东西,也就是在<>之间的内容。对于结果字符串是否完全安全,没有任何保证。所以在没有先进行转义的情况下,绝对不要把strip_tag的结果标记为安全,比如用escape()进行转义。”

关于Python的Bleach文档写道:

“Bleach的主要目标是清理用户输入,这些输入可以包含一些HTML作为标记,并且要包含在更大页面的内容中。”

因为用户输入不允许包含任何HTML,我猜Bleach可能不需要……不过我还是个新手,所以希望能得到一些建议。

2 个回答

1

如果你需要把输入标记为“安全”,只是为了让你插入的 <br> 标签能够显示出来,这样用户输入的换行就能正常显示,那么最好的办法就是使用 linebreaks 过滤器。根据Django 的文档

linebreaks

这个功能会把普通文本中的换行符替换成合适的 HTML 标签;一个换行符会变成一个 HTML 换行标签 (<br />),而一个换行符后面跟着一个空行会变成一个段落标签 (</p>)。

举个例子:

{{ value|linebreaks }}

如果输入的内容是 Joel\nis a slug, 那么输出的结果会是 <p>Joel<br />is a slug</p>.

与其在数据库里用正则表达式把换行符替换成 <br>,不如就直接把用户输入的数据保留原样。然后,你可以在模板中用

{{ text|striptags|linebreaks }}

这样做会先去掉用户输入中的大部分 HTML 标签,然后再为换行符添加 <br><p> 标签。不过,这样做并不会把字符串标记为安全,所以用户输入中剩下的标签会被转义;只有 linebreaks 生成的标签才会生效。

(如果你不想要 <p> 标签,可以使用变体过滤器 linebreaksbr。)

3

引用一下关于 striptags文档

没有安全保证

要注意,striptags 并不能保证它的输出完全安全,特别是当输入的 HTML 不合法时。所以,绝对不要对 striptags 的输出使用安全过滤器。如果你想要更可靠的解决方案,可以使用 bleach 这个 Python 库,特别是它的 clean 方法。

我认为这里的答案是使用 bleach 来去掉标签,简单得像 bleach.clean(text,tags=[])。而且,使用 bleach 的 linkefy 你还可以处理网址。

关于你的整体流程,如果这个字符串只生成一次但查询多次……为什么你不在保存时就添加换行和网址呢?

撰写回答