golang防xss核心是正确使用html/template:必须导入"html/template"、用{{.field}}插入变量、禁用text/template和template.html绕过;富文本须先经bluemonday白名单过滤再转template.html,且href等属性需校验协议、加引号并用对应类型包装。

为什么用 html/template 还被 XSS 了
大概率是混用了 text/template,或者在不该绕过转义的地方强行用了 template.HTML。只要导入的是 "html/template"、变量通过 {{.Name}} 直接插入、且没手动包装成 template.HTML,<script>alert(1)</script> 就只会显示为纯文本,不会执行。
常见错误现象:
- 用
template.Must(template.New("").Parse(...))却没指定包路径,实际加载的是text/template(因为没显式 import,Go 可能 fallback 到同名但不同包的默认) - 把用户提交的富文本字段直接转成
template.HTML(userInput)后传入模板——这是主动开后门 - 在
href="{{.URL}}"中插入未校验的用户输入,即使加了引号,javascript:alert(1)仍可能被浏览器执行(html/template不拦截协议,只做属性值转义)
怎么安全地插入富文本内容
必须分两步:前端提交时限制格式 + 后端清洗 + 显式标注可信。不能跳过任何一环。
正确做法:
- 后端接收富文本后,先用
bluemonday等专用库白名单过滤(只保留p、strong、img等安全标签及src、alt等属性) - 过滤后的字符串再转成
template.HTML类型:SafeContent: template.HTML(cleaned) - 模板里写
{{.SafeContent}},不加任何 filter,不调用safeHTML(该函数 Go 1.12+ 已弃用) - 禁止对原始
userInput做strings.ReplaceAll或正则“消毒”——这会破坏上下文转义逻辑,还可能漏掉onerror这类事件属性
在 href、onclick、style 里插数据为什么还是危险
html/template 的转义是上下文感知的,但它不负责判断语义合法性。比如它知道 href="..." 是 URL 上下文,会转义 " 和 &,但不会拒绝 javascript: 协议或 expression() CSS 写法。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
安全边界很明确:
- URL 类型字段应传
url.URL或用template.URL包装,而不是 string - JS 字符串必须用
{{.Data | js}}(注意:仅在模板内生效,且要求数据已按 JS 字符串规则预处理) - 动态 style 值建议避免,若必须用,类型应为
template.CSS,且禁止拼接用户可控的 CSS 表达式 - 绝对不要写
<a href="%7B%7B.URL%7D%7D"></a>(缺引号),这会让模板无法识别上下文,导致转义失效
什么时候该换 text/template
当你输出的不是 HTML,而是 XML、JSON、邮件正文、日志片段这类纯文本格式时,html/template 的自动转义反而会坏事——比如生成 Sitemap.xml 时,<url></url> 会被转成 <url></url>,XML 解析器直接报错。
此时必须切到 "text/template":
- 导入路径是
"text/template",不是"html/template" - 所有转义责任回到开发者手上:需手动调用
xml.EscapeString、json.Marshal或url.QueryEscape - 别指望
{{.Data}}自动帮你保安全;也别在text/template里用template.HTML——类型不兼容,运行时报错
最易忽略的一点:模板文件本身不能由用户控制路径或内容。哪怕用了 html/template,如果 template.ParseFiles(userInput),攻击者就能上传恶意模板并执行任意 Go 代码。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










