首页 > 后端开发 > Golang > 正文

输出格式要求:标题:Go 模板中安全地允许特定 HTML 标签

碧海醫心
发布: 2025-08-30 15:13:22
原创
310人浏览过

输出格式要求:标题:Go 模板中安全地允许特定 HTML 标签

第一段引用上面的摘要:

gohtml/template 包中,处理来自不可信来源的 html 内容时,直接使用 html 类型可能会引入安全风险。本文介绍了一种通过解析 html 并仅保留特定允许的标签,从而安全地在 go 模板中渲染部分 html 内容的方法。该方法利用第三方库,例如 go-html-transform,来解析 html,过滤掉未授权的标签和属性,并最终生成安全可信的输出,从而避免潜在的跨站脚本攻击(xss)。

在 Web 应用程序中,尤其是论坛或评论系统,经常需要处理用户提交的 HTML 内容。直接将这些内容未经处理地渲染到页面上,会带来严重的安全风险,例如跨站脚本攻击(XSS)。Go 的 html/template 包提供了强大的 HTML 转义功能,可以有效地防止 XSS 攻击。然而,在某些情况下,我们可能希望允许用户使用一些基本的 HTML 标签,例如 <b>、<i>、<br> 等,来实现简单的格式化。

一种安全的做法是解析 HTML 内容,并仅保留允许的标签和属性。这可以通过以下步骤实现:

  1. 使用 HTML 解析器: 选择一个合适的 HTML 解析器。go-html-transform 是一个常用的选择,因为它专门设计用于转换和清理 HTML。虽然 Go 1 移除了 exp/html,但 go-html-transform 提供了类似的功能,并且更加健壮。

  2. 定义白名单: 创建一个白名单,其中包含允许的 HTML 标签和属性。例如,我们可能允许 p、br、b、i 标签,以及 href 属性(仅用于 a 标签)。

    立即学习前端免费学习笔记(深入)”;

  3. 解析和过滤: 使用 HTML 解析器解析用户提交的 HTML 内容。然后,遍历解析后的 HTML 树,移除所有不在白名单中的标签和属性。

    Boomy
    Boomy

    AI音乐生成工具,创建生成音乐,与世界分享.

    Boomy 272
    查看详情 Boomy
  4. 生成安全 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 解析和过滤可能比较耗时,尤其是在处理大型 HTML 文档时。考虑使用缓存或其他优化技术来提高性能。
  • 复杂性: HTML 解析是一项复杂的任务,需要处理各种边缘情况。确保选择一个成熟、可靠的 HTML 解析器。
  • 安全: 仔细审查白名单,确保只允许必要的标签和属性。避免允许可能导致 XSS 攻击的标签和属性,例如 script、onload 等。
  • 转义: 即使使用了白名单,仍然建议对输出的 HTML 进行转义,以防止意外的 XSS 攻击。Go 的 html/template 包会自动进行转义。

总结:

通过解析 HTML 并仅保留白名单中的标签和属性,可以安全地在 Go 模板中渲染部分 HTML 内容。这种方法可以有效地防止 XSS 攻击,同时允许用户使用一些基本的 HTML 格式化。请务必谨慎选择 HTML 解析器,并仔细审查白名单,以确保应用程序的安全性。 使用 go-html-transform 库能够方便地实现 HTML 的解析和清理,并提供更安全的 HTML 输出。

以上就是输出格式要求:标题:Go 模板中安全地允许特定 HTML 标签的详细内容,更多请关注php中文网其它相关文章!

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号