Files
EdgeNode/internal/waf/checkpoints/request_upload.go

141 lines
3.4 KiB
Go
Raw Normal View History

2020-10-08 15:06:42 +08:00
package checkpoints
import (
"bytes"
"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
2022-04-08 16:11:05 +08:00
"github.com/TeaOSLab/EdgeNode/internal/waf/utils"
2020-10-08 15:06:42 +08:00
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
2022-08-04 11:34:06 +08:00
"io"
2020-10-08 15:06:42 +08:00
"net/http"
"path/filepath"
"strings"
)
2021-07-18 15:51:49 +08:00
// RequestUploadCheckpoint ${requestUpload.arg}
2020-10-08 15:06:42 +08:00
type RequestUploadCheckpoint struct {
Checkpoint
}
func (this *RequestUploadCheckpoint) RequestValue(req requests.Request, param string, options maps.Map, ruleId int64) (value interface{}, hasRequestBody bool, sysErr error, userErr error) {
2022-03-16 17:06:26 +08:00
if this.RequestBodyIsEmpty(req) {
value = ""
return
}
2020-10-08 15:06:42 +08:00
value = ""
if param == "minSize" || param == "maxSize" {
value = 0
}
2021-07-18 15:51:49 +08:00
if req.WAFRaw().Method != http.MethodPost {
2020-10-08 15:06:42 +08:00
return
}
2021-07-18 15:51:49 +08:00
if req.WAFRaw().Body == nil {
2020-10-08 15:06:42 +08:00
return
}
2022-07-16 17:05:37 +08:00
hasRequestBody = true
2021-07-18 15:51:49 +08:00
if req.WAFRaw().MultipartForm == nil {
var bodyData = req.WAFGetCacheBody()
if len(bodyData) == 0 {
2022-04-08 16:11:05 +08:00
data, err := req.WAFReadBody(utils.MaxBodySize)
2020-10-08 15:06:42 +08:00
if err != nil {
sysErr = err
return
}
2021-07-18 15:51:49 +08:00
bodyData = data
req.WAFSetCacheBody(data)
defer req.WAFRestoreBody(data)
2020-10-08 15:06:42 +08:00
}
2021-07-18 15:51:49 +08:00
oldBody := req.WAFRaw().Body
2022-08-04 11:34:06 +08:00
req.WAFRaw().Body = io.NopCloser(bytes.NewBuffer(bodyData))
2020-10-08 15:06:42 +08:00
2022-04-08 16:11:05 +08:00
err := req.WAFRaw().ParseMultipartForm(utils.MaxBodySize)
2020-10-08 15:06:42 +08:00
// 还原
2021-07-18 15:51:49 +08:00
req.WAFRaw().Body = oldBody
2020-10-08 15:06:42 +08:00
if err != nil {
userErr = err
return
}
2021-07-18 15:51:49 +08:00
if req.WAFRaw().MultipartForm == nil {
2020-10-08 15:06:42 +08:00
return
}
}
if param == "field" { // field
fields := []string{}
2021-07-18 15:51:49 +08:00
for field := range req.WAFRaw().MultipartForm.File {
2020-10-08 15:06:42 +08:00
fields = append(fields, field)
}
value = strings.Join(fields, ",")
} else if param == "minSize" { // minSize
minSize := int64(0)
2021-07-18 15:51:49 +08:00
for _, files := range req.WAFRaw().MultipartForm.File {
2020-10-08 15:06:42 +08:00
for _, file := range files {
if minSize == 0 || minSize > file.Size {
minSize = file.Size
}
}
}
value = minSize
} else if param == "maxSize" { // maxSize
maxSize := int64(0)
2021-07-18 15:51:49 +08:00
for _, files := range req.WAFRaw().MultipartForm.File {
2020-10-08 15:06:42 +08:00
for _, file := range files {
if maxSize < file.Size {
maxSize = file.Size
}
}
}
value = maxSize
} else if param == "name" { // name
names := []string{}
2021-07-18 15:51:49 +08:00
for _, files := range req.WAFRaw().MultipartForm.File {
2020-10-08 15:06:42 +08:00
for _, file := range files {
if !lists.ContainsString(names, file.Filename) {
names = append(names, file.Filename)
}
}
}
value = strings.Join(names, ",")
} else if param == "ext" { // ext
extensions := []string{}
2021-07-18 15:51:49 +08:00
for _, files := range req.WAFRaw().MultipartForm.File {
2020-10-08 15:06:42 +08:00
for _, file := range files {
if len(file.Filename) > 0 {
exit := strings.ToLower(filepath.Ext(file.Filename))
if !lists.ContainsString(extensions, exit) {
extensions = append(extensions, exit)
}
}
}
}
value = strings.Join(extensions, ",")
}
return
}
func (this *RequestUploadCheckpoint) ResponseValue(req requests.Request, resp *requests.Response, param string, options maps.Map, ruleId int64) (value interface{}, hasRequestBody bool, sysErr error, userErr error) {
2020-10-08 15:06:42 +08:00
if this.IsRequest() {
return this.RequestValue(req, param, options, ruleId)
2020-10-08 15:06:42 +08:00
}
return
}
func (this *RequestUploadCheckpoint) ParamOptions() *ParamOptions {
option := NewParamOptions()
option.AddParam("最小文件尺寸", "minSize")
option.AddParam("最大文件尺寸", "maxSize")
option.AddParam("扩展名(如.txt)", "ext")
option.AddParam("原始文件名", "name")
option.AddParam("表单字段名", "field")
return option
}