
在 go 的 html/template 包中,处理来自不可信来源的 html 内容时,直接使用 html 类型可能会引入安全风险。本文介绍了一种通过解析 html 并仅保留特定允许的标签,从而安全地在 go 模板中渲染部分 html 内容的方法。该方法利用第三方库,例如 go-html-transform,来解析 html,过滤掉未授权的标签和属性,并最终生成安全可信的输出,从而避免潜在的跨站脚本攻击(xss)。
在 Web 应用程序中,尤其是论坛或评论系统,经常需要处理用户提交的 HTML 内容。直接将这些内容未经处理地渲染到页面上,会带来严重的安全风险,例如跨站脚本攻击(XSS)。Go 的 html/template 包提供了强大的 HTML 转义功能,可以有效地防止 XSS 攻击。然而,在某些情况下,我们可能希望允许用户使用一些基本的 HTML 标签,例如 <b>、<i>、<br> 等,来实现简单的格式化。
一种安全的做法是解析 HTML 内容,并仅保留允许的标签和属性。这可以通过以下步骤实现:
使用 HTML 解析器: 选择一个合适的 HTML 解析器。go-html-transform 是一个常用的选择,因为它专门设计用于转换和清理 HTML。虽然 Go 1 移除了 exp/html,但 go-html-transform 提供了类似的功能,并且更加健壮。
定义白名单: 创建一个白名单,其中包含允许的 HTML 标签和属性。例如,我们可能允许 p、br、b、i 标签,以及 href 属性(仅用于 a 标签)。
立即学习“前端免费学习笔记(深入)”;
解析和过滤: 使用 HTML 解析器解析用户提交的 HTML 内容。然后,遍历解析后的 HTML 树,移除所有不在白名单中的标签和属性。
生成安全 HTML: 将过滤后的 HTML 树重新序列化为 HTML 字符串。这个字符串可以安全地在模板中渲染,因为它只包含允许的标签和属性。
示例代码 (使用 go-html-transform):
package main
import (
"fmt"
"strings"
"github.com/jaytaylor/html2text"
"golang.org/x/net/html"
)
// allowedTags 定义允许的 HTML 标签
var allowedTags = map[string]bool{
"p": true,
"br": true,
"b": true,
"i": true,
"a": true,
}
// allowedAttributes 定义允许的 HTML 属性,以及允许的标签
var allowedAttributes = map[string]map[string]bool{
"a": {"href": true},
}
// sanitizeHTML 对 HTML 进行清理,只保留白名单中的标签和属性
func sanitizeHTML(htmlString string) (string, error) {
root, err := html.Parse(strings.NewReader(htmlString))
if err != nil {
return "", err
}
var f func(*html.Node)
f = func(n *html.Node) {
// 移除不在白名单中的标签
if n.Type == html.ElementNode {
if _, ok := allowedTags[n.Data]; !ok {
n.Type = html.TextNode
n.Data = "" // 移除标签内容
} else {
// 清理属性
var attrs []html.Attribute
for _, attr := range n.Attr {
if allowedAttributes[n.Data] == nil || allowedAttributes[n.Data][attr.Key] {
attrs = append(attrs, attr)
}
}
n.Attr = attrs
}
}
// 递归处理子节点
for c := n.FirstChild; c != nil; c = c.NextSibling {
f(c)
}
}
f(root)
// 将 HTML 树重新序列化为字符串
sanitizedHTML, err := html2text.RenderNode(root)
if err != nil {
return "", err
}
return sanitizedHTML, nil
}
func main() {
untrustedHTML := `<p>This is a <b>bold</b> text with a <script>alert("XSS")</script> and <a href="https://example.com">link</a>.</p>`
safeHTML, err := sanitizeHTML(untrustedHTML)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Original HTML:", untrustedHTML)
fmt.Println("Sanitized HTML:", safeHTML)
}注意事项:
总结:
通过解析 HTML 并仅保留白名单中的标签和属性,可以安全地在 Go 模板中渲染部分 HTML 内容。这种方法可以有效地防止 XSS 攻击,同时允许用户使用一些基本的 HTML 格式化。请务必谨慎选择 HTML 解析器,并仔细审查白名单,以确保应用程序的安全性。 使用 go-html-transform 库能够方便地实现 HTML 的解析和清理,并提供更安全的 HTML 输出。
以上就是输出格式要求:标题:Go 模板中安全地允许特定 HTML 标签的详细内容,更多请关注php中文网其它相关文章!
HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号