在开发评论模块时,我们常需要集成 Markdown 语法支持。早期方案中,直接在模板中使用自定义过滤器配合 safe 标签看似可行:
{{ content|markdown_change|safe }}
但实际测试中发现,若未做严格清洗,恶意脚本仍可注入。
问题复现
当用户在评论中输入 <script>alert("XSS")</script> 并提交时,如果后端处理不当,该脚本将在浏览器端执行,造成安全隐患。
解决方案
方案一:引入第三方库
社区中有成熟的库如 markdown_deux,默认配置下会自动转义 HTML 标签。安装后可直接使用 {% load markdown_deux_tags %} 配合 {{ content|markdown }} 过滤器。
若需自定义样式,可在 settings.py 中调整 MARKDOWN_DEUX_STYLES,设置 safe_mode 为 escape 等参数。但这会增加项目依赖。
方案二:使用 Django 内置函数(推荐)
对于轻量级需求,无需引入额外库。Django 提供了 strip_tags 工具,可在转换前移除所有 HTML 标签,从而从源头杜绝 XSS。
核心逻辑是在调用 markdown.markdown 之前先执行 strip_tags。
from django import template
import markdown
from django.utils.html import strip_tags
register = template.Library()
@register.filter
def markdown_change(content):
# 先去除所有 HTML 标签,防止 XSS 攻击
content = strip_tags(content)
# 再进行 Markdown 转换
content = markdown.markdown(
content,
extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
'markdown.extensions.toc',
],
safe_mode=True
)
return content
这种方式既保留了 Markdown 的排版能力,又确保了内容的安全性,且无需额外依赖。


