xss

package module
v1.1.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 15, 2023 License: MIT Imports: 5 Imported by: 1

README

GoDoc Build Status Go Report Card Coverage Status GitHub license

go-xss 根据白名单过滤 HTML(防止 XSS 攻击)

go-xss is a module used to filter input from users to prevent XSS attacks

go-xss是一个用于对用户输入的内容进行过滤,以避免遭受 XSS 攻击的模块((什么是 XSS 攻击?)。主要用于论坛、博客、网上商店等等一些可允许用户录入页面排版、格式控制相关的 HTML 的场景,xss模块通过白名单来控制允许的标签及相关的标签属性,另外还提供了一系列的接口以便用户扩展,比其他同类模块更为灵活。

English | 中文文档

特性

  • 白名单控制允许的 HTML 标签及各标签的属性
  • 通过自定义处理函数,可对任意标签及其属性进行处理

性能

speed: 24MB/s

安装

go get -u github.com/feiin/go-xss

使用


import (
    "github.com/feiin/go-xss"
)


source := "<a href=\"javascript:alert(/xss/)\" title=\"hi\">link</a>"

safeHtml := xss.FilterXSS(source,xss.XssOption{})


import (
    "github.com/feiin/go-xss"
)

source := "<a href=\"javascript:alert(/xss/)\" title=\"hi\">link</a>"
x := xss.NewXSS(xss.XssOption{})
safeHtml := x.Process(source)

自定义过滤规则(options)

在调用 xss 进行过滤时,可通过options参数来设置自定义规则:

source := "<a href=\"javascript:alert(/xss/)\" title=\"hi\">link</a>"

options := xss.XssOption{}
safeHtml := xss.FilterXSS(source,options)

如果不想每次都传入一个 options 参数,可以创建一个 XSS 实例:

source := "<a href=\"javascript:alert(/xss/)\" title=\"hi\">link</a>"
options := xss.XssOption{}

x := xss.NewXSS(options)
safeHtml := x.Process(source)
白名单

通过 WhiteList 来指定,格式类型为:map[string][]string。不在白名单上的标签将被过滤,不在白名单上的属性也会被过滤。以下是示例:

// 只允许a标签,该标签只允许href, title, target这三个属性
options.WhiteList = map[string][]string {
		"a":{"href","title","target"},
}
// 使用以上配置后,下面的HTML
// <a href="#" onclick="hello()"><i>大家好</i></a>
// 将被过滤为
// <a href="#">大家好</a>

默认白名单参考 xss.GetDefaultWhiteList()

自定义匹配到标签时的处理方法

通过 OnTag 来指定相应的处理函数。以下是详细说明:

func onTag(tag, html string, options TagOption) *string {
	// tag是当前的标签名称,比如<a>标签,则tag的值是'a'
  // html是该标签的HTML,比如<a>标签,则html的值是'<a>'
  // options是一些附加的信息,具体如下:
  //   isWhite    boolean类型,表示该标签是否在白名单上
  //   isClosing  boolean类型,表示该标签是否为闭合标签,比如</a>时为true
  //   position        integer类型,表示当前标签在输出的结果中的起始位置
  //   sourcePosition  integer类型,表示当前标签在原HTML中的起始位置
  // 如果返回一个字符串,则当前标签将被替换为该字符串
  // 如果返回nil,则使用默认的处理方法:
  //   在白名单上:  通过onTagAttr来过滤属性,详见下文
  //   不在白名单上:通过onIgnoreTag指定,详见下文
}
自定义匹配到标签的属性时的处理方法

通过 OnTagAttr 来指定相应的处理函数。以下是详细说明:

func OnTagAttr(tag, name, value string,isWhiteAttr bool) *string {
	// tag是当前的标签名称,比如<a>标签,则tag的值是'a'
  // name是当前属性的名称,比如href="#",则name的值是'href'
  // value是当前属性的值,比如href="#",则value的值是'#'
  // isWhiteAttr是否为白名单上的属性
  // 如果返回一个字符串,则当前属性值将被替换为该字符串
  // 如果返回nil,则使用默认的处理方法
  //   在白名单上:  调用safeAttrValue来过滤属性值,并输出该属性,详见下文
  //   不在白名单上:通过onIgnoreTagAttr指定,详见下文
}

自定义匹配到不在白名单上的标签时的处理方法

通过 OnIgnoreTag 来指定相应的处理函数。以下是详细说明:

func OnIgnoreTag(tag, html string, options TagOption) *string {
	// 参数说明与onTag相同
  // 如果返回非nil,则当前标签将被替换为该字符串
  // 如果返回nil,则使用默认的处理方法(通过escape指定,详见下文)
}
自定义匹配到不在白名单上的属性时的处理方法

通过 OnIgnoreTagAttr 来指定相应的处理函数。以下是详细说明:

func OnIgnoreTagAttr(tag,name, value string,isWhiteAttr bool) *string {
  // 参数说明与onTagAttr相同
  // 如果返回一个字符串,则当前属性值将被替换为该字符串
  // 如果返回nil,则使用默认的处理方法(删除该属)
}
自定义 HTML 转义函数

通过 EscapeHtml 来指定相应的处理函数。以下是默认代码 (不建议修改) :

func EscapeHTML(html string) string {
	return regGT.ReplaceAllString(regLT.ReplaceAllString(html,"&lt;"),"&gt;")
}

自定义标签属性值的转义函数

通过 SafeAttrValue 来指定相应的处理函数。以下是详细说明:

func SafeAttrValue(tag, name, value string) string {
// 参数说明与onTagAttr相同(没有options参数)
  // 返回一个字符串表示该属性值

}
自定义 CSS 过滤器

TODO

快捷配置

去掉不在白名单上的标签

通过 StripIgnoreTag 来设置:

  • true:去掉不在白名单上的标签
  • false:(默认),使用配置的escape函数对该标签进行转义 示例:

当设置 StripIgnoreTag = true时,以下代码

code:<script>alert(/xss/);</script>

过滤后将输出

code:alert(/xss/);
去掉不在白名单上的标签及标签体

通过 StripIgnoreTagBody 来设置:

  • nil时:(默认),不特殊处理
  • []string{}:(空数组) 去掉所有不在白名单上的标签
  • []string{"tag1", "tag2"}:仅去掉指定的不在白名单上的标签

示例:

当设置 StripIgnoreTagBody = []string{"script"}时,以下代码

code:<script>alert(/xss/);</script>

过滤后将输出

code:

去掉 HTML 备注

通过 AllowCommentTag 来设置:

  • true:不处理
  • false:(默认),自动去掉 HTML 中的备注 示例:

当设置 AllowCommentTag = false 时,以下代码

code:<!-- something --> END

过滤后将输出

code: END

应用实例

允许标签以 data-开头的属性

	source := "<div a=\"1\" b=\"2\" data-a=\"3\" data-b=\"4\">hello</div>";

	html := xss.FilterXSS(source,xss.XssOption{
			OnIgnoreTagAttr: func(tag,name, value string,isWhiteAttr bool) *string {
				if len(name)>=5 && name[0:5] == "data-" {
					ret := name + "=\"" + xss.EscapeAttrValue(value)+"\""
					return &ret
				}
				return nil
			},
	})
	fmt.Printf("%s\nconvert to:\n%s", source, html);

运行结果:

<div a="1" b="2" data-a="3" data-b="4">hello</div>
convert to:
<div data-a="3" data-b="4">hello</div>

允许名称以 x-开头的标签

	source := "<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>";

	html := xss.FilterXSS(source,xss.XssOption{
			OnIgnoreTag: func(tag, html string, options xss.TagOption) *string {
				if len(tag)>=2 && tag[0:2] == "x-" {
					return &html;
				}
				return nil
			},
	})
	fmt.Printf("%s\nconvert to:\n%s", source, html);

运行结果

<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>
convert to:
&lt;x&gt;<x-1>he<x-2 checked></x-2>wwww</x-1><a>
分析 HTML 代码中的图片列表
	source := "<img src=\"img1\">a<img src=\"img2\">b<img src=\"img3\">c<img src=\"img4\">d"
	var list []string
	html := xss.FilterXSS(source,xss.XssOption{
			OnTagAttr: func(tag, name, value string ,isWhiteAttr bool) *string {
				if tag == "img" && name == "src" {
					list = append(list,value)
				}
				return nil
			},
	})
	fmt.Printf("image list:\n%s", strings.Join(list, ","));

运行结果:

image list:
img1, img2, img3, img4
去除 HTML 标签(只保留文本内容)
	source := "<strong>hello</strong><script>alert(/xss/);</script>end"
	html := xss.FilterXSS(source,xss.XssOption{
			WhiteList:map[string][]string{},  // // empty, means filter out all tags
			StripIgnoreTag:true, // filter out all HTML not in the whitelist
			StripIgnoreTagBody:[]string{"script"}, // the script tag is a special case, we need
	})
	fmt.Printf("text: %s", html);

运行结果:

text: helloend

Inspirations

License

MIT

Documentation

Overview

Example
source := "<div a=\"1\" b=\"2\" data-a=\"3\" data-b=\"4\">hello</div>"

html := xss.FilterXSS(source, xss.XssOption{})
fmt.Printf("%s\nconvert to:\n%s", source, html)

//To avoid passing options every time, you can also do it in a faster way by creating a NewXSS instance:

source = "<div a=\"1\" b=\"2\" data-a=\"3\" data-b=\"4\">hello</div>"

options := xss.XssOption{}

x := xss.NewXSS(options)

html = x.Process(source)
fmt.Printf("%s\nconvert to:\n%s", source, html)
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func EscapeAttrValue

func EscapeAttrValue(str string) string

func FilterXSS

func FilterXSS(html string, options XssOption) string

FilterXSS filter xss func

func FriendlyAttrValue

func FriendlyAttrValue(str string) string

FriendlyAttrValue get friendly attribute value

func GetDefaultWhiteList

func GetDefaultWhiteList() map[string][]string

GetDefaultWhiteList 默认白名单

Types

type AttrResult

type AttrResult struct {
	Html    string
	Closing bool
}

func GetAttrs

func GetAttrs(html string) AttrResult

type OnIgnoreTagFunc

type OnIgnoreTagFunc func(tag string, html string, options TagOption) *string

type OnTagFunc

type OnTagFunc func(sourcePosition int, position int, tag string, html string, isClosing bool) string

type StripTagBodyResult

type StripTagBodyResult struct {
	OnIgnoreTag OnIgnoreTagFunc
	Remove      func(html string) string
}

type TagOption

type TagOption struct {
	SourcePosition int
	Position       int
	IsClosing      bool
	IsWhite        bool
}

type Xss

type Xss struct {
	// contains filtered or unexported fields
}

func NewXSS

func NewXSS(options XssOption) *Xss

NewXSS

func (*Xss) Process

func (x *Xss) Process(html string) string

Process 处理xss

type XssOption

type XssOption struct {

	//remove invisible characters
	StripBlankChar bool

	// remove html comments
	AllowCommentTag bool

	StripIgnoreTag bool

	// StripIgnoreTagBody
	StripIgnoreTagBody []string

	WhiteList map[string][]string

	OnTag func(tag, html string, options TagOption) *string

	OnIgnoreTag func(tag, html string, options TagOption) *string

	OnTagAttr func(tag, name, value string, isWhiteAttr bool) *string

	OnIgnoreTagAttr func(tag, name, value string, isWhiteAttr bool) *string

	StripTagBody  func(tags []string, next OnIgnoreTagFunc) StripTagBodyResult
	SafeAttrValue func(tag, name, value string) string
	EscapeHTML    func(html string) string
}

func NewDefaultXssOption

func NewDefaultXssOption() XssOption

NewDefaultXssOption

func NewXssOption

func NewXssOption() XssOption

NewXssOption

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL