Browse Source

Merge branch 'hotfix/jinbo_test_0329' into debug

# Conflicts:
#	utils/common.go
xyxie 1 year ago
parent
commit
666829ba89
7 changed files with 214 additions and 2 deletions
  1. 19 1
      controllers/english_report/report.go
  2. 44 0
      controllers/report.go
  3. 71 0
      controllers/resource.go
  4. 3 0
      go.mod
  5. 6 0
      go.sum
  6. 6 0
      services/report.go
  7. 65 1
      utils/common.go

+ 19 - 1
controllers/english_report/report.go

@@ -65,6 +65,12 @@ func (this *EnglishReportController) Add() {
 
 	var contentSub string
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			br.Msg = "存在非法标签"
+			br.ErrMsg = "存在非法标签, Err: " + e.Error()
+			return
+		}
 		content, e := services.FilterReportContentBr(req.Content)
 		if e != nil {
 			br.Msg = "内容去除前后空格失败"
@@ -182,6 +188,12 @@ func (this *EnglishReportController) Edit() {
 	}
 	var contentSub string
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			br.Msg = "存在非法标签"
+			br.ErrMsg = "存在非法标签, Err: " + e.Error()
+			return
+		}
 		content, e := services.FilterReportContentBr(req.Content)
 		if e != nil {
 			br.Msg = "内容去除前后空格失败"
@@ -956,7 +968,7 @@ func (this *EnglishReportController) Delete() {
 	go func() {
 		_ = services.ResetPPTReport(req.ReportIds, true)
 	}()
-	
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "删除成功"
@@ -1013,6 +1025,12 @@ func (this *EnglishReportController) SaveReportContent() {
 			content = this.GetString("Content")
 		}
 		if content != "" {
+			e := utils.ContentXssFilter(req.Content)
+			if e != nil {
+				br.Msg = "存在非法标签"
+				br.ErrMsg = "存在非法标签, Err: " + e.Error()
+				return
+			}
 			contentClean, e := services.FilterReportContentBr(req.Content)
 			if e != nil {
 				br.Msg = "内容去除前后空格失败"

+ 44 - 0
controllers/report.go

@@ -525,6 +525,12 @@ func (this *ReportController) Add() {
 	}
 	var contentSub string
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			br.Msg = "存在非法标签"
+			br.ErrMsg = "存在非法标签, Err: " + e.Error()
+			return
+		}
 		content, e := services.FilterReportContentBr(req.Content)
 		if e != nil {
 			br.Msg = "内容去除前后空格失败"
@@ -659,6 +665,12 @@ func (this *ReportController) Edit() {
 	}
 	var contentSub string
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			br.Msg = "存在非法标签"
+			br.ErrMsg = "存在非法标签, Err: " + e.Error()
+			return
+		}
 		content, e := services.FilterReportContentBr(req.Content)
 		if e != nil {
 			br.Msg = "内容去除前后空格失败"
@@ -913,6 +925,20 @@ func (this *ReportController) Upload() {
 		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
 		return
 	}
+
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
+		return
+	}
+	pass := filetype.IsImage(fileData)
+	if !pass {
+		br.Msg = "文件格式有误"
+		br.ErrMsg = "文件格式有误"
+		return
+	}
+
 	ext := path.Ext(h.Filename)
 	dateDir := time.Now().Format("20060102")
 	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
@@ -1193,6 +1219,12 @@ func (this *ReportController) SaveReportContent() {
 			content = this.GetString("Content")
 		}
 		if content != "" {
+			e := utils.ContentXssFilter(req.Content)
+			if e != nil {
+				br.Msg = "存在非法标签"
+				br.ErrMsg = "存在非法标签, Err: " + e.Error()
+				return
+			}
 			contentClean, e := services.FilterReportContentBr(req.Content)
 			if e != nil {
 				br.Msg = "内容去除前后空格失败"
@@ -2427,6 +2459,12 @@ func (this *ReportController) EditDayWeekChapter() {
 	// 更新章节及指标
 	contentSub := ""
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			br.Msg = "存在非法标签"
+			br.ErrMsg = "存在非法标签, Err: " + e.Error()
+			return
+		}
 		contentClean, e := services.FilterReportContentBr(req.Content)
 		if e != nil {
 			br.Msg = "内容去除前后空格失败"
@@ -2898,6 +2936,12 @@ func (this *ReportController) PublishDayWeekReportChapter() {
 	// 更新章节信息
 	contentSub := ""
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			br.Msg = "存在非法标签"
+			br.ErrMsg = "存在非法标签, Err: " + e.Error()
+			return
+		}
 		contentClean, e := services.FilterReportContentBr(req.Content)
 		if e != nil {
 			br.Msg = "内容去除前后空格失败"

+ 71 - 0
controllers/resource.go

@@ -7,8 +7,10 @@ import (
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
 	"fmt"
+	"github.com/h2non/filetype"
 	"github.com/kgiannakakis/mp3duration/src/mp3duration"
 	"io"
+	"io/ioutil"
 	"net/http"
 	"os"
 	"path"
@@ -45,6 +47,20 @@ func (this *ResourceController) Upload() {
 		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
 		return
 	}
+
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
+		return
+	}
+	pass := filetype.IsImage(fileData)
+	if !pass {
+		br.Msg = "文件格式有误"
+		br.ErrMsg = "文件格式有误"
+		return
+	}
+
 	uploadFileName := h.Filename //上传的文件名
 	ext := path.Ext(h.Filename)
 	dateDir := time.Now().Format("20060102")
@@ -142,6 +158,20 @@ func (this *ResourceController) VideoUpload() {
 		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
 		return
 	}
+
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
+		return
+	}
+	pass := filetype.IsVideo(fileData)
+	if !pass {
+		br.Msg = "文件格式有误"
+		br.ErrMsg = "文件格式有误"
+		return
+	}
+
 	ext := path.Ext(h.Filename)
 	dateDir := time.Now().Format("20060102")
 	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
@@ -354,6 +384,19 @@ func (this *ResourceController) VoiceUpload() {
 	}
 	uploadFileName := h.Filename //上传的文件名
 
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
+		return
+	}
+	pass := filetype.IsAudio(fileData)
+	if !pass {
+		br.Msg = "文件格式有误"
+		br.ErrMsg = "文件格式有误"
+		return
+	}
+
 	ext := path.Ext(h.Filename)
 	dateDir := time.Now().Format("20060102")
 	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
@@ -612,6 +655,20 @@ func (this *ResourceController) UploadImageBase64() {
 			br.ErrMsg = "获取资源信息失败,Err:" + e.Error()
 			return
 		}
+
+		fileData, e := ioutil.ReadAll(f)
+		if e != nil {
+			br.Msg = "上传失败"
+			br.ErrMsg = "读取文件失败, Err: " + e.Error()
+			return
+		}
+		pass := filetype.IsImage(fileData)
+		if !pass {
+			br.Msg = "文件格式有误"
+			br.ErrMsg = "文件格式有误"
+			return
+		}
+
 		ext = path.Ext(h.Filename)
 		dateDir := time.Now().Format("20060102")
 		uploadDir = utils.STATIC_DIR + "hongze/" + dateDir
@@ -792,6 +849,20 @@ func (this *ResourceController) UploadV2() {
 		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
 		return
 	}
+
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
+		return
+	}
+	pass := filetype.IsImage(fileData)
+	if !pass {
+		br.Msg = "文件格式有误"
+		br.ErrMsg = "文件格式有误"
+		return
+	}
+
 	ext := path.Ext(h.Filename)
 	dateDir := time.Now().Format("20060102")
 	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir

+ 3 - 0
go.mod

@@ -28,6 +28,7 @@ require (
 	github.com/h2non/filetype v1.1.3
 	github.com/jung-kurt/gofpdf v1.16.2
 	github.com/kgiannakakis/mp3duration v0.0.0-20191013070830-d834f8d5ed53
+	github.com/microcosm-cc/bluemonday v1.0.26
 	github.com/minio/minio-go/v7 v7.0.69
 	github.com/mojocn/base64Captcha v1.3.6
 	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
@@ -58,6 +59,7 @@ require (
 	github.com/aliyun/credentials-go v1.3.1 // indirect
 	github.com/andybalholm/cascadia v1.3.2 // indirect
 	github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20211218165449-dd623ecc2f02 // indirect
+	github.com/aymerick/douceur v0.2.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
@@ -75,6 +77,7 @@ require (
 	github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9 // indirect
 	github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 // indirect
 	github.com/google/uuid v1.6.0 // indirect
+	github.com/gorilla/css v1.0.0 // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect

+ 6 - 0
go.sum

@@ -91,6 +91,8 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoU
 github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
 github.com/aws/aws-sdk-go v1.51.2 h1:Ruwgz5aqIXin5Yfcgc+PCzoqW5tEGb9aDL/JWDsre7k=
 github.com/aws/aws-sdk-go v1.51.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 github.com/beego/bee/v2 v2.1.0 h1:4WngbAnkvVOyKy74WXcRH3clon76wkjhuzrV2mx2fQU=
 github.com/beego/bee/v2 v2.1.0/go.mod h1:wDhKy5TNxv46LHKsK2gyxo38ObCOm9PbCN89lWHK3EU=
 github.com/beego/beego/v2 v2.1.0 h1:Lk0FtQGvDQCx5V5yEu4XwDsIgt+QOlNjt5emUa3/ZmA=
@@ -238,6 +240,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
+github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
 github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
@@ -302,6 +306,8 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
 github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
+github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
 github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
 github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
 github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0=

+ 6 - 0
services/report.go

@@ -952,6 +952,12 @@ func PcCreateAndUploadSunCode(scene, page string) (imgUrl string, err error) {
 func CreateNewReport(req models.AddReq, adminInfo *system.Admin) (newReportId int64, reportCode, errMsg string, err error) {
 	contentSub := ""
 	if req.Content != "" {
+		e := utils.ContentXssFilter(req.Content)
+		if e != nil {
+			errMsg = "存在非法标签"
+			err = errors.New("存在非法标签, Err: " + e.Error())
+			return
+		}
 		contentClean, e := FilterReportContentBr(req.Content)
 		if e != nil {
 			errMsg = "内容去除前后空格失败"

+ 65 - 1
utils/common.go

@@ -14,7 +14,7 @@ import (
 	"fmt"
 	"github.com/PuerkitoBio/goquery"
 	"github.com/shopspring/decimal"
-	"html"
+	"golang.org/x/net/html"
 	"image"
 	"image/png"
 	"io"
@@ -2341,3 +2341,67 @@ func MillisecondsToHHMMSS(ms int) string {
 func ByteToMB(byteCount int) float64 {
 	return float64(byteCount) / (1024 * 1024)
 }
+
+// 检查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) (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
+}