瀏覽代碼

上传接口文件格式校验, Cookie设置HTTPOnly

hsun 11 月之前
父節點
當前提交
28ffe207d6
共有 9 個文件被更改,包括 69 次插入107 次删除
  1. 18 44
      controllers/banner.go
  2. 4 0
      controllers/base_auth.go
  3. 3 0
      controllers/base_common.go
  4. 11 12
      controllers/cloud_disk.go
  5. 19 38
      controllers/report.go
  6. 1 0
      go.mod
  7. 2 0
      go.sum
  8. 2 4
      models/company/company_config.go
  9. 9 9
      routers/commentsRouter.go

+ 18 - 44
controllers/banner.go

@@ -2,12 +2,12 @@ package controllers
 
 import (
 	"eta/eta_api/models"
-	"eta/eta_api/models/company"
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
+	"github.com/h2non/filetype"
+	"io/ioutil"
 	"os"
 	"path"
-	"strings"
 	"time"
 )
 
@@ -44,24 +44,23 @@ func (this *BannerController) Upload() {
 		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
 		return
 	}
+	defer f.Close() //关闭上传文件
 
-	// 限制文件类型
-	confVal, e := company.GetConfigDetailByCode(company.ConfUploadAllowImgExt)
-	if e != nil && e.Error() != utils.ErrNoRow() {
-		br.Msg = "操作失败"
-		br.ErrMsg = "文件上传失败, Err: " + e.Error()
+	// 不依赖于文件扩展名检查文件格式
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
 		return
 	}
-	allowExt := make([]string, 0)
-	if confVal.ConfigValue != "" {
-		allowExt = strings.Split(confVal.ConfigValue, ",")
-	}
-	ext := path.Ext(h.Filename)
-	if !utils.InArrayByStr(allowExt, ext) {
-		br.Msg = "图片格式有误"
+	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
 	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
@@ -73,22 +72,18 @@ func (this *BannerController) Upload() {
 	randStr := utils.GetRandStringNoSpecialChar(28)
 	fileName := randStr + ext
 	fpath := uploadDir + "/" + fileName
-	defer f.Close() //关闭上传文件
 	err = this.SaveToFile("file", fpath)
 	if err != nil {
 		br.Msg = "文件上传失败"
 		br.ErrMsg = "文件上传失败,Err:" + err.Error()
 		return
 	}
-	resourceUrl := ``
-
-	//resourceUrl, err = services.UploadImgToMinIoTest(fileName, fpath)
-	//if err != nil {
-	//	br.Msg = "文件上传失败"
-	//	br.ErrMsg = "文件上传失败,Err:" + err.Error()
-	//	return
-	//}
+	defer func() {
+		os.Remove(fpath)
+	}()
 
+	// 上传文件
+	resourceUrl := ``
 	ossClient := services.NewOssClient()
 	if ossClient == nil {
 		br.Msg = "上传失败"
@@ -102,27 +97,6 @@ func (this *BannerController) Upload() {
 		return
 	}
 
-	////上传到阿里云 和 minio
-	//if utils.ObjectStorageClient == "minio" {
-	//	resourceUrl, err = services.UploadImgToMinIo(fileName, fpath)
-	//	if err != nil {
-	//		br.Msg = "文件上传失败"
-	//		br.ErrMsg = "文件上传失败,Err:" + err.Error()
-	//		return
-	//	}
-	//} else {
-	//	resourceUrl, err = services.UploadAliyunV2(fileName, fpath)
-	//	if err != nil {
-	//		br.Msg = "文件上传失败"
-	//		br.ErrMsg = "文件上传失败,Err:" + err.Error()
-	//		return
-	//	}
-	//}
-
-	defer func() {
-		os.Remove(fpath)
-	}()
-
 	item := new(models.Resource)
 	item.ResourceUrl = resourceUrl
 	item.ResourceType = 1

+ 4 - 0
controllers/base_auth.go

@@ -308,6 +308,10 @@ func (c *BaseAuthController) JSON(data interface{}, hasIndent bool, coding bool)
 	c.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
 	desEncrypt := utils.DesBase64Encrypt([]byte(utils.DesKey), utils.DesKeySalt)
 	c.Ctx.Output.Header("Dk", string(desEncrypt)) // des3加解密key
+	// 设置Cookie为HTTPOnly
+	c.Ctx.SetCookie("", "", -1, "/", "", false, true, "")
+	//fmt.Println(c.Ctx.ResponseWriter.Header().Get("Set-Cookie"))
+
 	var content []byte
 	var err error
 	if hasIndent {

+ 3 - 0
controllers/base_common.go

@@ -87,6 +87,9 @@ func (c *BaseCommonController) JSON(data interface{}, hasIndent bool, coding boo
 	c.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
 	desEncrypt := utils.DesBase64Encrypt([]byte(utils.DesKey), utils.DesKeySalt)
 	c.Ctx.Output.Header("Dk", string(desEncrypt)) // des3加解密key
+	// 设置Cookie为HTTPOnly
+	c.Ctx.SetCookie("", "", -1, "/", "", false, true, "")
+
 	var content []byte
 	var err error
 	if hasIndent {

+ 11 - 12
controllers/cloud_disk.go

@@ -4,12 +4,13 @@ import (
 	"archive/zip"
 	"encoding/json"
 	"eta/eta_api/models"
-	"eta/eta_api/models/company"
 	"eta/eta_api/services"
 	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/utils"
 	"fmt"
+	"github.com/h2non/filetype"
 	"github.com/rdlucklib/rdluck_tools/http"
+	"io/ioutil"
 	"os"
 	"path"
 	"strconv"
@@ -558,20 +559,17 @@ func (this *CloudDiskController) ResourceUpload() {
 	extIndex := strings.LastIndex(originName, ".")
 	fileName := originName[:extIndex]
 
-	// 限制文件类型
-	confVal, e := company.GetConfigDetailByCode(company.ConfCloudDiskAllowExt)
-	if e != nil && e.Error() != utils.ErrNoRow() {
-		br.Msg = "操作失败"
-		br.ErrMsg = "文件上传失败, Err: " + e.Error()
+	// 不依赖于文件扩展名检查文件格式
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
 		return
 	}
-	allowExt := make([]string, 0)
-	if confVal.ConfigValue != "" {
-		allowExt = strings.Split(confVal.ConfigValue, ",")
-	}
-	ext := path.Ext(h.Filename)
-	if !utils.InArrayByStr(allowExt, ext) {
+	// 允许上传图片/音视频/文档/压缩包
+	if !filetype.IsImage(fileData) && !filetype.IsVideo(fileData) && !filetype.IsAudio(fileData) && !filetype.IsDocument(fileData) && !filetype.IsArchive(fileData) {
 		br.Msg = "不允许上传该格式文件"
+		br.ErrMsg = "文件格式有误"
 		return
 	}
 
@@ -596,6 +594,7 @@ func (this *CloudDiskController) ResourceUpload() {
 		br.ErrMsg = "存储目录创建失败, Err:" + e.Error()
 		return
 	}
+	ext := path.Ext(h.Filename)
 	ossFileName := utils.GetRandStringNoSpecialChar(28) + ext
 	filePath := uploadDir + "/" + ossFileName
 	if e = this.SaveToFile("file", filePath); e != nil {

+ 19 - 38
controllers/report.go

@@ -3,7 +3,6 @@ package controllers
 import (
 	"encoding/json"
 	"eta/eta_api/models"
-	"eta/eta_api/models/company"
 	"eta/eta_api/models/report_approve"
 	"eta/eta_api/services"
 	"eta/eta_api/services/alarm_msg"
@@ -11,9 +10,11 @@ import (
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/beego/beego/v2/server/web"
+	"github.com/h2non/filetype"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"github.com/tealeg/xlsx"
 	"html"
+	"io/ioutil"
 	"os"
 	"path"
 	"path/filepath"
@@ -1226,7 +1227,7 @@ func (this *ReportController) SaveReportContent() {
 // @Param   File   query   file  true       "文件"
 // @Success 200 上传成功
 // @router /uploadImg [post]
-func (this *ReportController) UploadImg() {
+func (this *ReportCommonController) UploadImg() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
 		if br.ErrMsg == "" {
@@ -1235,13 +1236,6 @@ func (this *ReportController) UploadImg() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	sysUser := this.SysUser
-	if sysUser == nil {
-		br.Msg = "请登录"
-		br.ErrMsg = "请登录,SysUser Is Empty"
-		br.Ret = 408
-		return
-	}
 
 	var err error
 	defer func() {
@@ -1255,24 +1249,23 @@ func (this *ReportController) UploadImg() {
 	if err != nil {
 		return
 	}
+	defer f.Close() //关闭上传文件
 
-	// 限制文件类型
-	confVal, e := company.GetConfigDetailByCode(company.ConfUploadAllowImgExt)
-	if e != nil && e.Error() != utils.ErrNoRow() {
-		br.Msg = "操作失败"
-		br.ErrMsg = "文件上传失败, Err: " + e.Error()
+	// 不依赖于文件扩展名检查文件格式
+	fileData, e := ioutil.ReadAll(f)
+	if e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "读取文件失败, Err: " + e.Error()
 		return
 	}
-	allowExt := make([]string, 0)
-	if confVal.ConfigValue != "" {
-		allowExt = strings.Split(confVal.ConfigValue, ",")
-	}
-	ext := path.Ext(h.Filename)
-	if !utils.InArrayByStr(allowExt, ext) {
-		br.Msg = "图片格式有误"
+	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
 	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
@@ -1282,24 +1275,16 @@ func (this *ReportController) UploadImg() {
 	randStr := utils.GetRandStringNoSpecialChar(28)
 	fileName := randStr + ext
 	fpath := uploadDir + "/" + fileName
-	defer f.Close() //关闭上传文件
 	err = this.SaveToFile("file", fpath)
 	if err != nil {
 		return
 	}
+	defer func() {
+		os.Remove(fpath)
+	}()
+
+	// 上传至对象存储
 	resourceUrl := ``
-	//上传到阿里云 和 minio
-	//if utils.ObjectStorageClient == "minio" {
-	//	resourceUrl, err = services.UploadImgToMinIo(fileName, fpath)
-	//	if err != nil {
-	//		return
-	//	}
-	//} else {
-	//	resourceUrl, err = services.UploadAliyunV2(fileName, fpath)
-	//	if err != nil {
-	//		return
-	//	}
-	//}
 	ossClient := services.NewOssClient()
 	if ossClient == nil {
 		err = fmt.Errorf("初始化OSS服务失败")
@@ -1311,10 +1296,6 @@ func (this *ReportController) UploadImg() {
 		return
 	}
 
-	defer func() {
-		os.Remove(fpath)
-	}()
-
 	item := new(models.Resource)
 	item.ResourceUrl = resourceUrl
 	item.ResourceType = 1

+ 1 - 0
go.mod

@@ -24,6 +24,7 @@ require (
 	github.com/go-xorm/xorm v0.7.9
 	github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
 	github.com/gorilla/websocket v1.5.1
+	github.com/h2non/filetype v1.1.3
 	github.com/kgiannakakis/mp3duration v0.0.0-20191013070830-d834f8d5ed53
 	github.com/minio/minio-go/v7 v7.0.69
 	github.com/mojocn/base64Captcha v1.3.6

+ 2 - 0
go.sum

@@ -234,6 +234,8 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51
 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=
+github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
+github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
 github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
 github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=

+ 2 - 4
models/company/company_config.go

@@ -5,10 +5,8 @@ import (
 )
 
 const (
-	ConfAreaCodeListKey   = "area_code_list"       // 手机号区号列表
-	ConfEnAuthRoleKey     = "en_auth_role"         // 英文权限角色配置Key
-	ConfCloudDiskAllowExt = "cloud_disk_allow_ext" // 云盘允许上传的文件类型
-	ConfUploadAllowImgExt = "upload_allow_img_ext" // 允许上传的图片文件类型
+	ConfAreaCodeListKey = "area_code_list" // 手机号区号列表
+	ConfEnAuthRoleKey   = "en_auth_role"   // 英文权限角色配置Key
 )
 
 type CrmConfig struct {

+ 9 - 9
routers/commentsRouter.go

@@ -7054,6 +7054,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers:ReportCommonController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ReportCommonController"],
+        beego.ControllerComments{
+            Method: "UploadImg",
+            Router: `/uploadImg`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers:ReportController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ReportController"],
         beego.ControllerComments{
             Method: "CheckDayWeekReportChapterVideo",
@@ -7405,15 +7414,6 @@ func init() {
             Filters: nil,
             Params: nil})
 
-    beego.GlobalControllerRouter["eta/eta_api/controllers:ReportController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ReportController"],
-        beego.ControllerComments{
-            Method: "UploadImg",
-            Router: `/uploadImg`,
-            AllowHTTPMethods: []string{"post"},
-            MethodParams: param.Make(),
-            Filters: nil,
-            Params: nil})
-
     beego.GlobalControllerRouter["eta/eta_api/controllers:ResearchGroupController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ResearchGroupController"],
         beego.ControllerComments{
             Method: "GetAdminResearchGroup",