|
@@ -13,9 +13,8 @@ import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"github.com/PuerkitoBio/goquery"
|
|
|
- "github.com/microcosm-cc/bluemonday"
|
|
|
"github.com/shopspring/decimal"
|
|
|
- "html"
|
|
|
+ "golang.org/x/net/html"
|
|
|
"image"
|
|
|
"image/png"
|
|
|
"io"
|
|
@@ -2299,9 +2298,66 @@ func GetColorMap() map[int]string {
|
|
|
return colorMap
|
|
|
}
|
|
|
|
|
|
+// 检查src属性是否以http或data:image开头
|
|
|
+func isValidSrc(src string) bool {
|
|
|
+ validSchemes := regexp.MustCompile(`^(http|https|data:image)/`)
|
|
|
+ return validSchemes.MatchString(src)
|
|
|
+}
|
|
|
+
|
|
|
// ContentXssFilter 过滤文本中的JS代码
|
|
|
-func ContentXssFilter(content string) (clean string) {
|
|
|
- p := bluemonday.UGCPolicy()
|
|
|
- clean = p.Sanitize(content)
|
|
|
+func ContentXssFilter(content string) (err error) {
|
|
|
+ // 解析HTML内容
|
|
|
+ node, err := html.Parse(strings.NewReader(content))
|
|
|
+ if err != nil {
|
|
|
+ err = fmt.Errorf(" html.Parse Err: %v", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 遍历解析后的节点树,查找特定标签
|
|
|
+ var visit func(n *html.Node)
|
|
|
+ visit = func(n *html.Node) {
|
|
|
+ if n.Type == html.ElementNode {
|
|
|
+ lowerData := strings.ToLower(n.Data)
|
|
|
+ switch lowerData {
|
|
|
+ case "script", "javascript":
|
|
|
+ err = fmt.Errorf(" script is forbidden")
|
|
|
+ return
|
|
|
+ case "img", "input", "iframe":
|
|
|
+ // 查找并过滤src属性
|
|
|
+ for _, attr := range n.Attr {
|
|
|
+ lowerKey := strings.ToLower(attr.Key)
|
|
|
+ if lowerKey == "src" {
|
|
|
+ if !isValidSrc(attr.Val) {
|
|
|
+ err = fmt.Errorf("invalid src attribute value: %s", attr.Val)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ for _, attr := range n.Attr { //判断事件
|
|
|
+ lowerKey := strings.ToLower(attr.Key)
|
|
|
+ if lowerKey == "onmouseover" || lowerKey == "onclick" || lowerKey == "onerror" {
|
|
|
+ err = fmt.Errorf("the event is forbidden: %s:%s", attr.Key, attr.Val)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* case "src":
|
|
|
+ // 如果<src>是某个标签的属性,你可能需要递归检查其父节点
|
|
|
+ // 这里简单起见,我们假设<src>不是有效的HTML标签,并忽略它
|
|
|
+ // 在实际中,你可能需要更复杂的逻辑来处理这种情况
|
|
|
+ fmt.Println("Warning: Unexpected 'src' tag found.")*/
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
|
+ visit(c)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ visit(node)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
return
|
|
|
}
|