Django安全处理用户输入。html.strip_tags足够吗,还是应该使用bleach?
我在一个小论坛上接受用户输入,处理用户输入的步骤如下:
首先,我使用“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 个回答
如果你需要把输入标记为“安全”,只是为了让你插入的 <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
。)
引用一下关于 striptags
的 文档
没有安全保证
要注意,striptags 并不能保证它的输出完全安全,特别是当输入的 HTML 不合法时。所以,绝对不要对 striptags 的输出使用安全过滤器。如果你想要更可靠的解决方案,可以使用 bleach 这个 Python 库,特别是它的 clean 方法。
我认为这里的答案是使用 bleach
来去掉标签,简单得像 bleach.clean(text,tags=[])
。而且,使用 bleach 的 linkefy
你还可以处理网址。
关于你的整体流程,如果这个字符串只生成一次但查询多次……为什么你不在保存时就添加换行和网址呢?