使用html/template可自动防御XSS,因其能根据上下文对变量进行安全转义。1. 在HTML文本、属性、JS、URL等上下文中,特殊字符如、"及javascript:伪协议会被正确编码;2. 用户输入的alert(1)将被转义为纯文本输出;3. 使用{{.}}插入数据时,确保类型为string,避免手动拼接HTML字符串;4. 若需输出可信HTML,应使用template.HTML等安全类型,但必须确保来源可信;5. 推荐将原始数据传入模板,由模板引擎自动处理转义,而非在Go代码中拼接HTML。核心原则是:信任边界清晰,仅在必要时关闭转义。

Go 语言的 html/template 包在设计上就考虑了安全问题,能自动对输出内容进行上下文相关的转义,有效防止 XSS(跨站脚本)攻击。只要正确使用,无需手动调用 escape 函数。
自动转义机制
html/template 会根据数据插入的位置(HTML 标签内、属性、JavaScript、URL 等)自动应用不同的转义规则:
- 在 HTML 文本中: 转为 zuojiankuohaophpcn,> 转为 youjiankuohaophpcn
- 在 HTML 属性中:双引号会被转义为 "
- 在 JavaScript 字符串中:单引号、反斜杠等特殊字符也会被转义
- 在 URL 中:如 javascript: 伪协议会被清理或编码
这意味着即使用户输入 ,在模板中渲染时也会变成纯文本,不会执行。
正确使用模板变量
确保使用 html/template 而不是 text/template,并用 {{.}} 正确插入变量:
立即学习“go语言免费学习笔记(深入)”;
// handler.gotmpl := template.Must(template.New("demo").Parse(`
{{.Content}}
`))data := struct{ Content string }{Content: ""}
tmpl.Execute(w, data)
输出结果为:
zuojiankuohaophpcnscriptyoujiankuohaophpcnalert('xss')zuojiankuohaophpcn/scriptyoujiankuohaophpcn
脚本不会执行,仅显示原文本。
处理可信 HTML 内容
如果某些 HTML 是可信的(如后台富文本编辑器输入),需要显式标记为安全类型 template.HTML:
data := struct{ Content template.HTML }{Content: template.HTML("加粗文本"),
}
此时内容不会被转义。但必须确保来源可信,否则会引入 XSS 风险。
类似类型还有:
template.JS(安全的 JS)
template.URL(安全的 URL)
template.CSS(安全的 CSS)
避免手动拼接 HTML
不要在 Go 代码中拼接 HTML 字符串再传给模板,这样容易绕过转义机制:
// 错误做法dangerous := fmt.Sprintf("点击", userURL)
// 即使使用 html/template,拼接后无法再安全转义
应将原始数据传入模板,由模板引擎负责转义:
{{printf "点击" .UserURL}}或更推荐:
点击模板会自动对 URL 属性进行转义。
基本上就这些。只要坚持使用 html/template,不滥用 template.HTML,不手动拼接 HTML,就能在大多数场景下有效防御 XSS。安全的核心在于“信任边界”——只在明确可信的地方关闭转义。










