xss is a module used to filter input from users to prevent XSS attacks. (What is XSS attack?)
中文文档 | English
Specifies HTML tags and their attributes allowed with whitelist Handle any tags or attributes using custom function.
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)
When using the xss, the options parameter could be used to specify custom rules:
source := "<a href=\"javascript:alert(/xss/)\" title=\"hi\">link</a>"
options := xss.XssOption{}
safeHtml := xss.FilterXSS(source,options)
To avoid passing options every time, you can also do it in a faster way by creating a NewXSS instance:
source := "<a href=\"javascript:alert(/xss/)\" title=\"hi\">link</a>"
options := xss.XssOption{}
x := xss.NewXSS(options)
safeHtml := x.Process(source)
By specifying a whiteList, e.g. map[string][]string
. Tags and attributes not in the whitelist would be filter out. For example:
// only tag a and its attributes href, title, target are allowed
options.WhiteList = map[string][]string {
"a":{"href","title","target"},
}
// With the configuration specified above, the following HTML:
// <a href="#" onclick="hello()"><i>Hello</i></a>
// would become:
// <a href="#"><i>Hello</i></a>
For the default whitelist, please refer xss.GetDefaultWhiteList()
By specifying the handler function with OnTag:
func onTag(tag, html string, options TagOption) *string {
// tag is the name of current tag, e.g. 'a' for tag <a>
// html is the HTML of this tag, e.g. '<a>' for tag <a>
// options is some addition informations:
// isWhite boolean, whether the tag is in whitelist
// isClosing boolean, whether the tag is a closing tag, e.g. true for </a>
// position integer, the position of the tag in output result
// sourcePosition integer, the position of the tag in input HTML source
// If a string is returned, the current tag would be replaced with the string
// If return nil, the default measure would be taken:
// If in whitelist: filter attributes using onTagAttr, as described below
// If not in whitelist: handle by onIgnoreTag, as described below
}
By specifying the handler function with OnTagAttr:
func OnTagAttr(tag, name, value string,isWhiteAttr bool) *string {
// tag is the name of current tag, e.g. 'a' for tag <a>
// name is the name of current attribute, e.g. 'href' for href="#"
// isWhiteAttr whether the attribute is in whitelist
// If a string is returned, the attribute would be replaced with the string
// If return nil, the default measure would be taken:
// If in whitelist: filter the value using safeAttrValue as described below
// If not in whitelist: handle by onIgnoreTagAttr, as described below
}
By specifying the handler function with OnIgnoreTag:
func OnIgnoreTag(tag, html string, options TagOption) *string {
// Parameters are the same with onTag
// If a string is returned, the tag would be replaced with the string
// If return nil, the default measure would be taken (specifies using
// escape, as described below)
}
By specifying the handler function with onIgnoreTagAttr:
func OnIgnoreTagAttr(tag,name, value string,isWhiteAttr bool) *string {
// Parameters are the same with onTagAttr
// If a string is returned, the value would be replaced with this string
// If return nil, then keep default (remove the attribute)
}
By specifying the handler function with escapeHtml. Following is the default function (Modification is not recommended):
func EscapeHTML(html string) string {
return regGT.ReplaceAllString(regLT.ReplaceAllString(html,"<"),">")
}
By specifying the handler function with safeAttrValue:
func SafeAttrValue(tag, name, value string) string {
// Parameters are the same with onTagAttr (without options)
// Return the value as a string
}
By specifying a SingleQuotedAttributeValue
. Use true
for '
. Otherwise default "
will be used
options.SingleQuotedAttributeValue = true
// With the configuration specified above, the following HTML:
// <a href="#">Hello</a>
// would become:
// <a href='#'>Hello</a>
By using StripIgnoreTag
parameter:
true
filter out tags not in the whitelistfalse
: by default: escape the tag using configuredescape
function
Example:
If StripIgnoreTag = true
is set, the following code:
code:<script>alert(/xss/);</script>
would output filtered:
code:alert(/xss/);
By using StripIgnoreTagBody
parameter:
nil
by default: do nothing[]string{}
: (empty array) filter out all tags not in the whitelist[]string{"tag1", "tag2"}
: filter out only specified tags not in the whitelist
Example:
If StripIgnoreTagBody = []string{"script"}
is set, the following code:
code:<script>alert(/xss/);</script>
would output filtered:
code:
By using AllowCommentTag
parameter:
true
: do nothingfalse
by default: filter out HTML comments
Example:
If AllowCommentTag = false
is set, the following code:
code:<!-- something --> END
would output filtered:
code: END
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);
Result:
<div a="1" b="2" data-a="3" data-b="4">hello</div>
convert to:
<div data-a="3" data-b="4">hello</div>
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);
Result:
<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>
convert to:
<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>
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, ","));
Result:
image list:
img1, img2, img3, img4
source := "<strong>hello</strong><script>alert(/xss/);</script>end"
html := xss.FilterXSS(source,xss.XssOption{
WhiteList:map[string][]string{}, // 白名单为空,表示过滤所有标签
StripIgnoreTag:true, // 过滤所有非白名单标签的HTML
StripIgnoreTagBody:[]string{"script"}, //script标签较特殊,需要过滤标签中间的内容
})
fmt.Printf("text: %s", html);
Result:
text: helloend
MIT