golang HTML内容安全过滤与净化插件库bluemonday的使用

Golang HTML内容安全过滤与净化插件库bluemonday的使用

bluemonday是一个用Go语言实现的HTML净化器,它速度快且高度可配置。它接收不受信任的用户生成内容作为输入,并根据允许的HTML元素和属性列表返回经过净化的HTML,以便您可以安全地将内容包含在网页中。

基本用法

安装bluemonday:

go get github.com/microcosm-cc/bluemonday

基本使用示例:

package main

import (
    "fmt"

    "github.com/microcosm-cc/bluemonday"
)

func main() {
    // 为每个唯一的策略执行一次,并在程序生命周期内使用该策略
    // 策略创建/编辑不适用于多个goroutine
    p := bluemonday.UGCPolicy()

    // 然后可以使用该策略来净化大量输入,并且在多个goroutine中使用该策略是安全的
    html := p.Sanitize(
        `<a onblur="alert(secret)" href="http://www.google.com">Google</a>`,
    )

    // 输出:
    // <a href="http://www.google.com" rel="nofollow">Google</a>
    fmt.Println(html)
}

三种净化方式

bluemonday提供三种调用Sanitize的方式:

p.Sanitize(string) string
p.SanitizeBytes([]byte) []byte
p.SanitizeReader(io.Reader) bytes.Buffer

默认策略

bluemonday提供两种默认策略:

  1. bluemonday.StrictPolicy() - 相当于剥离所有HTML元素及其属性,因为它没有任何允许列表
  2. bluemonday.UGCPolicy() - 允许广泛选择对用户生成内容安全的HTML元素和属性

自定义策略构建

您可以构建自己的策略:

package main

import (
    "fmt"

    "github.com/microcosm-cc/bluemonday"
)

func main() {
    p := bluemonday.NewPolicy()

    // 要求URL可通过net/url.Parse解析,并且是mailto:、http://或https://
    p.AllowStandardURLs()

    // 我们只允许<p>和<a href="">
    p.AllowAttrs("href").OnElements("a")
    p.AllowElements("p")

    html := p.Sanitize(
        `<a onblur="alert(secret)" href="http://www.google.com">Google</a>`,
    )

    // 输出:
    // <a href="http://www.google.com">Google</a>
    fmt.Println(html)
}

添加元素到策略

添加元素到策略:

p.AllowElements("b", "strong")

或者使用正则表达式:

p.AllowElementsMatching(regex.MustCompile(`^my-element-`))

添加属性

添加属性到所有元素:

p.AllowAttrs("dir").Matching(regexp.MustCompile("(?i)rtl|ltr")).Globally()

添加属性到特定元素:

p.AllowAttrs("value").OnElements("li")

链接处理

链接是难以安全净化的内容之一,也是恶意内容的最大攻击媒介之一。

基本链接处理:

p.AllowAttrs("href").Matching(regexp.MustCompile(`(?i)mailto|https?`)).OnElements("a")

更安全的链接处理:

p.RequireParseableURLs(true)
p.AllowRelativeURLs(true)
p.AllowURLSchemes("mailto", "http", "https")
p.RequireNoFollowOnLinks(true)

数据URI

允许数据URI图像:

p.AllowDataURIImages()

策略构建辅助方法

bluemonday提供了一些辅助方法来简化策略构建:

// 全局允许"dir"、"id"、"lang"、"title"属性
p.AllowStandardAttributes()

// 允许"img"元素及其标准属性
p.AllowImages()

// 允许有序和无序列表,以及定义列表
p.AllowLists()

// 允许HTML表格及所有适用元素和非样式属性
p.AllowTables()

生产环境就绪性

bluemonday已在生产环境中使用,从广泛使用且经过大量现场测试的OWASP Java HTML Sanitizer迁移而来。它通过了广泛的测试套件(包括AntiSamy测试以及针对任何提出问题的测试)。

局限性

目前不包含任何帮助允许和净化CSS的工具。这意味着除非您希望在单个正则表达式中完成繁重的工作(不建议),否则您不应该在任何地方允许"style"属性。

同样,<script><style>被认为是有害的。默认情况下不会呈现这些元素(及其内容),并且需要您显式设置p.AllowUnsafe(true)


更多关于golang HTML内容安全过滤与净化插件库bluemonday的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang HTML内容安全过滤与净化插件库bluemonday的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


bluemonday - Go语言的HTML内容安全过滤库

bluemonday是一个用于Go语言的HTML内容安全过滤库,它可以帮助开发者净化用户输入的HTML内容,防止XSS(跨站脚本)攻击。下面我将详细介绍它的使用方法和示例代码。

基本特性

  • 允许开发者定义允许的HTML元素和属性
  • 移除所有不在白名单中的HTML标签和属性
  • 支持CSS过滤
  • 良好的性能表现
  • 易于扩展和定制

安装

go get github.com/microcosm-cc/bluemonday

基本使用示例

简单净化

package main

import (
	"fmt"
	
	"github.com/microcosm-cc/bluemonday"
)

func main() {
	// 创建一个严格的策略,只允许文本内容
	p := bluemonday.StrictPolicy()
	
	// 示例HTML输入
	html := `<b>粗体</b>和<script>alert('xss')</script>`
	
	// 净化HTML
	sanitized := p.Sanitize(html)
	
	fmt.Println(sanitized)
	// 输出: 粗体和
}

宽松策略示例

package main

import (
	"fmt"
	
	"github.com/microcosm-cc/bluemonday"
)

func main() {
	// 创建一个宽松的策略
	p := bluemonday.UGCPolicy()
	
	// 示例HTML输入
	html := `
		<h1>标题</h1>
		<p>段落<a href="https://example.com" onclick="alert('xss')">链接</a></p>
		<script>alert('xss')</script>
	`
	
	// 净化HTML
	sanitized := p.Sanitize(html)
	
	fmt.Println(sanitized)
	// 输出: <h1>标题</h1>
	//       <p>段落<a href="https://example.com">链接</a></p>
}

自定义策略

package main

import (
	"fmt"
	
	"github.com/microcosm-cc/bluemonday"
)

func main() {
	// 创建自定义策略
	p := bluemonday.NewPolicy()
	
	// 允许基本标签
	p.AllowStandardAttributes()
	p.AllowElements("p", "b", "i", "u", "a")
	
	// 允许a标签的href属性,但限制协议
	p.AllowAttrs("href").OnElements("a")
	p.RequireParseableURLs(true)
	p.AllowURLSchemes("http", "https")
	
	// 示例HTML输入
	html := `
		<p>段落<b>加粗</b>和<i>斜体</i></p>
		<a href="https://example.com">安全链接</a>
		<a href="javascript:alert('xss')">危险链接</a>
	`
	
	// 净化HTML
	sanitized := p.Sanitize(html)
	
	fmt.Println(sanitized)
	// 输出: <p>段落<b>加粗</b>和<i>斜体</i></p>
	//       <a href="https://example.com">安全链接</a>
	//       危险链接
}

高级用法

允许特定CSS类

p := bluemonday.NewPolicy()
p.AllowElements("div", "span")
p.AllowAttrs("class").OnElements("div", "span")
p.AllowClasses(map[string][]string{
	"div":  {"container", "wrapper"},
	"span": {"highlight"},
})

处理HTML片段

p := bluemonday.UGCPolicy()
html := `<p>段落</p><iframe src="http://example.com"></iframe>`
sanitized := p.Sanitize(html)
// iframe会被移除

处理相对URL

p := bluemonday.UGCPolicy()
p.AllowRelativeURLs(true)
p.RequireParseableURLs(true)

性能考虑

bluemonday在设计时就考虑了性能问题,但如果你需要处理大量HTML内容,可以考虑以下优化:

  1. 重用Policy对象,不要每次处理都创建新的
  2. 对于相同的净化规则,使用单例Policy
  3. 在可能的情况下,对输入内容先进行长度检查

最佳实践

  1. 默认使用最严格的策略,只按需放宽
  2. 对用户生成内容始终进行净化
  3. 结合其他安全措施如CSRF防护一起使用
  4. 定期检查并更新库版本

总结

bluemonday是Go语言中处理HTML内容安全的强大工具,它提供了灵活的配置选项和良好的默认策略。通过合理使用,可以有效地防止XSS攻击,同时保留必要的HTML格式。

更多高级用法和详细文档可以参考官方GitHub仓库:github.com/microcosm-cc/bluemonday

回到顶部