From b55cdc8067ace776b209b13743b6f44ead2caa07 Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Wed, 18 Nov 2020 19:35:38 +0800 Subject: [PATCH] =?UTF-8?q?[WAF]=E8=A7=84=E5=88=99=E4=B8=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=AF=B7=E6=B1=82Header=E9=95=BF=E5=BA=A6=E9=99=90?= =?UTF-8?q?=E5=88=B6=E5=92=8C=E5=93=8D=E5=BA=94Header=E9=95=BF=E5=BA=A6?= =?UTF-8?q?=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/const/const.go | 2 +- internal/nodes/listener_http.go | 4 +- internal/waf/checkpoints/cc.go | 4 +- internal/waf/checkpoints/checkpoint.go | 4 ++ .../waf/checkpoints/checkpoint_interface.go | 8 +++- internal/waf/checkpoints/request_all.go | 5 ++- internal/waf/checkpoints/request_arg.go | 5 ++- internal/waf/checkpoints/request_args.go | 5 ++- internal/waf/checkpoints/request_body.go | 5 ++- .../waf/checkpoints/request_content_type.go | 5 ++- internal/waf/checkpoints/request_cookie.go | 5 ++- internal/waf/checkpoints/request_cookies.go | 5 ++- internal/waf/checkpoints/request_form_arg.go | 5 ++- .../request_general_header_length.go | 40 +++++++++++++++++ internal/waf/checkpoints/request_header.go | 5 ++- internal/waf/checkpoints/request_headers.go | 5 ++- internal/waf/checkpoints/request_host.go | 5 ++- internal/waf/checkpoints/request_json_arg.go | 5 ++- internal/waf/checkpoints/request_length.go | 5 ++- internal/waf/checkpoints/request_method.go | 5 ++- internal/waf/checkpoints/request_path.go | 5 ++- internal/waf/checkpoints/request_proto.go | 5 ++- .../checkpoints/request_raw_remote_addr.go | 5 ++- internal/waf/checkpoints/request_referer.go | 5 ++- .../waf/checkpoints/request_remote_addr.go | 5 ++- .../waf/checkpoints/request_remote_port.go | 5 ++- .../waf/checkpoints/request_remote_user.go | 5 ++- internal/waf/checkpoints/request_scheme.go | 5 ++- internal/waf/checkpoints/request_upload.go | 5 ++- internal/waf/checkpoints/request_uri.go | 5 ++- .../waf/checkpoints/request_user_agent.go | 5 ++- internal/waf/checkpoints/response_body.go | 5 ++- .../waf/checkpoints/response_bytes_sent.go | 5 ++- .../response_general_header_length.go | 45 +++++++++++++++++++ internal/waf/checkpoints/response_header.go | 5 ++- internal/waf/checkpoints/response_status.go | 5 ++- internal/waf/checkpoints/utils.go | 14 ++++++ internal/waf/rule.go | 12 +++++ 38 files changed, 214 insertions(+), 64 deletions(-) create mode 100644 internal/waf/checkpoints/request_general_header_length.go create mode 100644 internal/waf/checkpoints/response_general_header_length.go diff --git a/internal/const/const.go b/internal/const/const.go index 0775da4..977c396 100644 --- a/internal/const/const.go +++ b/internal/const/const.go @@ -1,7 +1,7 @@ package teaconst const ( - Version = "0.0.1" + Version = "0.0.2" ProductName = "Edge Node" ProcessName = "edge-node" diff --git a/internal/nodes/listener_http.go b/internal/nodes/listener_http.go index 96e2e5b..e88e155 100644 --- a/internal/nodes/listener_http.go +++ b/internal/nodes/listener_http.go @@ -132,7 +132,9 @@ func (this *HTTPListener) handleHTTP(rawWriter http.ResponseWriter, rawReq *http mismatchAction := httpAllConfig.DomainMismatchAction if mismatchAction != nil && mismatchAction.Code == "page" { if mismatchAction.Options != nil { - http.Error(rawWriter, mismatchAction.Options.GetString("contentHTML"), mismatchAction.Options.GetInt("statusCode")) + rawWriter.Header().Set("Content-Type", "text/html; charset=utf-8") + rawWriter.WriteHeader(mismatchAction.Options.GetInt("statusCode")) + _, _ = rawWriter.Write([]byte(mismatchAction.Options.GetString("contentHTML"))) } else { http.Error(rawWriter, "404 page not found: '"+rawReq.URL.String()+"'", http.StatusNotFound) } diff --git a/internal/waf/checkpoints/cc.go b/internal/waf/checkpoints/cc.go index 89fe6e5..89a85be 100644 --- a/internal/waf/checkpoints/cc.go +++ b/internal/waf/checkpoints/cc.go @@ -31,7 +31,7 @@ func (this *CCCheckpoint) Start() { this.grid = grids.NewGrid(32, grids.NewLimitCountOpt(1000_0000)) } -func (this *CCCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *CCCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = 0 if this.grid == nil { @@ -121,7 +121,7 @@ func (this *CCCheckpoint) RequestValue(req *requests.Request, param string, opti return } -func (this *CCCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *CCCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/checkpoint.go b/internal/waf/checkpoints/checkpoint.go index 3b1475b..3535084 100644 --- a/internal/waf/checkpoints/checkpoint.go +++ b/internal/waf/checkpoints/checkpoint.go @@ -11,6 +11,10 @@ func (this *Checkpoint) IsRequest() bool { return true } +func (this *Checkpoint) IsComposed() bool { + return false +} + func (this *Checkpoint) ParamOptions() *ParamOptions { return nil } diff --git a/internal/waf/checkpoints/checkpoint_interface.go b/internal/waf/checkpoints/checkpoint_interface.go index db958f2..0a8ac8d 100644 --- a/internal/waf/checkpoints/checkpoint_interface.go +++ b/internal/waf/checkpoints/checkpoint_interface.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) // Check Point @@ -12,11 +13,14 @@ type CheckpointInterface interface { // is request? IsRequest() bool + // is composed? + IsComposed() bool + // get request value - RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) + RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) // get response value - ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) + ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) // param option list ParamOptions() *ParamOptions diff --git a/internal/waf/checkpoints/request_all.go b/internal/waf/checkpoints/request_all.go index 95d9c68..64664a6 100644 --- a/internal/waf/checkpoints/request_all.go +++ b/internal/waf/checkpoints/request_all.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) // ${requestAll} @@ -9,7 +10,7 @@ type RequestAllCheckpoint struct { Checkpoint } -func (this *RequestAllCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestAllCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { valueBytes := []byte{} if len(req.RequestURI) > 0 { valueBytes = append(valueBytes, req.RequestURI...) @@ -37,7 +38,7 @@ func (this *RequestAllCheckpoint) RequestValue(req *requests.Request, param stri return } -func (this *RequestAllCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestAllCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = "" if this.IsRequest() { return this.RequestValue(req, param, options) diff --git a/internal/waf/checkpoints/request_arg.go b/internal/waf/checkpoints/request_arg.go index 826c8d3..813fc51 100644 --- a/internal/waf/checkpoints/request_arg.go +++ b/internal/waf/checkpoints/request_arg.go @@ -2,17 +2,18 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestArgCheckpoint struct { Checkpoint } -func (this *RequestArgCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestArgCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { return req.URL.Query().Get(param), nil, nil } -func (this *RequestArgCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestArgCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_args.go b/internal/waf/checkpoints/request_args.go index 6b5f75d..9a3883c 100644 --- a/internal/waf/checkpoints/request_args.go +++ b/internal/waf/checkpoints/request_args.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestArgsCheckpoint struct { Checkpoint } -func (this *RequestArgsCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestArgsCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.URL.RawQuery return } -func (this *RequestArgsCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestArgsCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_body.go b/internal/waf/checkpoints/request_body.go index 5bd3bc3..d6e54ca 100644 --- a/internal/waf/checkpoints/request_body.go +++ b/internal/waf/checkpoints/request_body.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) // ${requestBody} @@ -9,7 +10,7 @@ type RequestBodyCheckpoint struct { Checkpoint } -func (this *RequestBodyCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestBodyCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if req.Body == nil { value = "" return @@ -28,7 +29,7 @@ func (this *RequestBodyCheckpoint) RequestValue(req *requests.Request, param str return req.BodyData, nil, nil } -func (this *RequestBodyCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestBodyCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_content_type.go b/internal/waf/checkpoints/request_content_type.go index 73c1d65..6a11132 100644 --- a/internal/waf/checkpoints/request_content_type.go +++ b/internal/waf/checkpoints/request_content_type.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestContentTypeCheckpoint struct { Checkpoint } -func (this *RequestContentTypeCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestContentTypeCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.Header.Get("Content-Type") return } -func (this *RequestContentTypeCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestContentTypeCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_cookie.go b/internal/waf/checkpoints/request_cookie.go index a6c6887..eb1ba91 100644 --- a/internal/waf/checkpoints/request_cookie.go +++ b/internal/waf/checkpoints/request_cookie.go @@ -2,13 +2,14 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestCookieCheckpoint struct { Checkpoint } -func (this *RequestCookieCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestCookieCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { cookie, err := req.Cookie(param) if err != nil { value = "" @@ -19,7 +20,7 @@ func (this *RequestCookieCheckpoint) RequestValue(req *requests.Request, param s return } -func (this *RequestCookieCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestCookieCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_cookies.go b/internal/waf/checkpoints/request_cookies.go index 1a12e2e..f284788 100644 --- a/internal/waf/checkpoints/request_cookies.go +++ b/internal/waf/checkpoints/request_cookies.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "net/url" "strings" ) @@ -10,7 +11,7 @@ type RequestCookiesCheckpoint struct { Checkpoint } -func (this *RequestCookiesCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestCookiesCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { var cookies = []string{} for _, cookie := range req.Cookies() { cookies = append(cookies, url.QueryEscape(cookie.Name)+"="+url.QueryEscape(cookie.Value)) @@ -19,7 +20,7 @@ func (this *RequestCookiesCheckpoint) RequestValue(req *requests.Request, param return } -func (this *RequestCookiesCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestCookiesCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_form_arg.go b/internal/waf/checkpoints/request_form_arg.go index 3d6535e..92fa0ab 100644 --- a/internal/waf/checkpoints/request_form_arg.go +++ b/internal/waf/checkpoints/request_form_arg.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "net/url" ) @@ -10,7 +11,7 @@ type RequestFormArgCheckpoint struct { Checkpoint } -func (this *RequestFormArgCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestFormArgCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if req.Body == nil { value = "" return @@ -31,7 +32,7 @@ func (this *RequestFormArgCheckpoint) RequestValue(req *requests.Request, param return values.Get(param), nil, nil } -func (this *RequestFormArgCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestFormArgCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_general_header_length.go b/internal/waf/checkpoints/request_general_header_length.go new file mode 100644 index 0000000..4f2a430 --- /dev/null +++ b/internal/waf/checkpoints/request_general_header_length.go @@ -0,0 +1,40 @@ +package checkpoints + +import ( + "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" + "github.com/iwind/TeaGo/types" +) + +type RequestGeneralHeaderLengthCheckpoint struct { + Checkpoint +} + +func (this *RequestGeneralHeaderLengthCheckpoint) IsComposed() bool { + return true +} + +func (this *RequestGeneralHeaderLengthCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { + value = false + + headers := options.GetSlice("headers") + if len(headers) == 0 { + return + } + + length := options.GetInt("length") + + for _, header := range headers { + v := req.Header.Get(types.String(header)) + if len(v) > length { + value = true + break + } + } + + return +} + +func (this *RequestGeneralHeaderLengthCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { + return +} diff --git a/internal/waf/checkpoints/request_header.go b/internal/waf/checkpoints/request_header.go index 553b515..029def4 100644 --- a/internal/waf/checkpoints/request_header.go +++ b/internal/waf/checkpoints/request_header.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "strings" ) @@ -9,7 +10,7 @@ type RequestHeaderCheckpoint struct { Checkpoint } -func (this *RequestHeaderCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestHeaderCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { v, found := req.Header[param] if !found { value = "" @@ -19,7 +20,7 @@ func (this *RequestHeaderCheckpoint) RequestValue(req *requests.Request, param s return } -func (this *RequestHeaderCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestHeaderCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_headers.go b/internal/waf/checkpoints/request_headers.go index c6acdbf..c5ef280 100644 --- a/internal/waf/checkpoints/request_headers.go +++ b/internal/waf/checkpoints/request_headers.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "sort" "strings" ) @@ -10,7 +11,7 @@ type RequestHeadersCheckpoint struct { Checkpoint } -func (this *RequestHeadersCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestHeadersCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { var headers = []string{} for k, v := range req.Header { for _, subV := range v { @@ -22,7 +23,7 @@ func (this *RequestHeadersCheckpoint) RequestValue(req *requests.Request, param return } -func (this *RequestHeadersCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestHeadersCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_host.go b/internal/waf/checkpoints/request_host.go index 68f8e26..60174d0 100644 --- a/internal/waf/checkpoints/request_host.go +++ b/internal/waf/checkpoints/request_host.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestHostCheckpoint struct { Checkpoint } -func (this *RequestHostCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestHostCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.Host return } -func (this *RequestHostCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestHostCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_json_arg.go b/internal/waf/checkpoints/request_json_arg.go index 5841e55..1a6414e 100644 --- a/internal/waf/checkpoints/request_json_arg.go +++ b/internal/waf/checkpoints/request_json_arg.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/TeaOSLab/EdgeNode/internal/utils" "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "strings" ) @@ -12,7 +13,7 @@ type RequestJSONArgCheckpoint struct { Checkpoint } -func (this *RequestJSONArgCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestJSONArgCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if len(req.BodyData) == 0 { data, err := req.ReadBody(int64(32 * 1024 * 1024)) // read 32m bytes if err != nil { @@ -36,7 +37,7 @@ func (this *RequestJSONArgCheckpoint) RequestValue(req *requests.Request, param return "", nil, nil } -func (this *RequestJSONArgCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestJSONArgCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_length.go b/internal/waf/checkpoints/request_length.go index 24f8718..9a09556 100644 --- a/internal/waf/checkpoints/request_length.go +++ b/internal/waf/checkpoints/request_length.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestLengthCheckpoint struct { Checkpoint } -func (this *RequestLengthCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestLengthCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.ContentLength return } -func (this *RequestLengthCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestLengthCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_method.go b/internal/waf/checkpoints/request_method.go index a2580be..b27deb0 100644 --- a/internal/waf/checkpoints/request_method.go +++ b/internal/waf/checkpoints/request_method.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestMethodCheckpoint struct { Checkpoint } -func (this *RequestMethodCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestMethodCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.Method return } -func (this *RequestMethodCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestMethodCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_path.go b/internal/waf/checkpoints/request_path.go index 776a6dc..7c934de 100644 --- a/internal/waf/checkpoints/request_path.go +++ b/internal/waf/checkpoints/request_path.go @@ -2,17 +2,18 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestPathCheckpoint struct { Checkpoint } -func (this *RequestPathCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestPathCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { return req.URL.Path, nil, nil } -func (this *RequestPathCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestPathCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_proto.go b/internal/waf/checkpoints/request_proto.go index 0c144f4..f3cd372 100644 --- a/internal/waf/checkpoints/request_proto.go +++ b/internal/waf/checkpoints/request_proto.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestProtoCheckpoint struct { Checkpoint } -func (this *RequestProtoCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestProtoCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.Proto return } -func (this *RequestProtoCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestProtoCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_raw_remote_addr.go b/internal/waf/checkpoints/request_raw_remote_addr.go index 9cab823..9da7f11 100644 --- a/internal/waf/checkpoints/request_raw_remote_addr.go +++ b/internal/waf/checkpoints/request_raw_remote_addr.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "net" ) @@ -9,7 +10,7 @@ type RequestRawRemoteAddrCheckpoint struct { Checkpoint } -func (this *RequestRawRemoteAddrCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRawRemoteAddrCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { host, _, err := net.SplitHostPort(req.RemoteAddr) if err == nil { value = host @@ -19,7 +20,7 @@ func (this *RequestRawRemoteAddrCheckpoint) RequestValue(req *requests.Request, return } -func (this *RequestRawRemoteAddrCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRawRemoteAddrCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_referer.go b/internal/waf/checkpoints/request_referer.go index 593784f..0160579 100644 --- a/internal/waf/checkpoints/request_referer.go +++ b/internal/waf/checkpoints/request_referer.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestRefererCheckpoint struct { Checkpoint } -func (this *RequestRefererCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRefererCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.Referer() return } -func (this *RequestRefererCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRefererCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_remote_addr.go b/internal/waf/checkpoints/request_remote_addr.go index c5a271c..b80e42b 100644 --- a/internal/waf/checkpoints/request_remote_addr.go +++ b/internal/waf/checkpoints/request_remote_addr.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "net" "strings" ) @@ -10,7 +11,7 @@ type RequestRemoteAddrCheckpoint struct { Checkpoint } -func (this *RequestRemoteAddrCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRemoteAddrCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { // X-Forwarded-For forwardedFor := req.Header.Get("X-Forwarded-For") if len(forwardedFor) > 0 { @@ -51,7 +52,7 @@ func (this *RequestRemoteAddrCheckpoint) RequestValue(req *requests.Request, par return } -func (this *RequestRemoteAddrCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRemoteAddrCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_remote_port.go b/internal/waf/checkpoints/request_remote_port.go index b5b9b1e..5f65c7e 100644 --- a/internal/waf/checkpoints/request_remote_port.go +++ b/internal/waf/checkpoints/request_remote_port.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/types" "net" ) @@ -10,7 +11,7 @@ type RequestRemotePortCheckpoint struct { Checkpoint } -func (this *RequestRemotePortCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRemotePortCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { _, port, err := net.SplitHostPort(req.RemoteAddr) if err == nil { value = types.Int(port) @@ -20,7 +21,7 @@ func (this *RequestRemotePortCheckpoint) RequestValue(req *requests.Request, par return } -func (this *RequestRemotePortCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRemotePortCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_remote_user.go b/internal/waf/checkpoints/request_remote_user.go index 0e95c8f..1c27cc8 100644 --- a/internal/waf/checkpoints/request_remote_user.go +++ b/internal/waf/checkpoints/request_remote_user.go @@ -2,13 +2,14 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestRemoteUserCheckpoint struct { Checkpoint } -func (this *RequestRemoteUserCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRemoteUserCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { username, _, ok := req.BasicAuth() if !ok { value = "" @@ -18,7 +19,7 @@ func (this *RequestRemoteUserCheckpoint) RequestValue(req *requests.Request, par return } -func (this *RequestRemoteUserCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestRemoteUserCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_scheme.go b/internal/waf/checkpoints/request_scheme.go index 63f2855..11e27e1 100644 --- a/internal/waf/checkpoints/request_scheme.go +++ b/internal/waf/checkpoints/request_scheme.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestSchemeCheckpoint struct { Checkpoint } -func (this *RequestSchemeCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestSchemeCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.URL.Scheme return } -func (this *RequestSchemeCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestSchemeCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_upload.go b/internal/waf/checkpoints/request_upload.go index 38ba070..d76656d 100644 --- a/internal/waf/checkpoints/request_upload.go +++ b/internal/waf/checkpoints/request_upload.go @@ -4,6 +4,7 @@ import ( "bytes" "github.com/TeaOSLab/EdgeNode/internal/waf/requests" "github.com/iwind/TeaGo/lists" + "github.com/iwind/TeaGo/maps" "io/ioutil" "net/http" "path/filepath" @@ -15,7 +16,7 @@ type RequestUploadCheckpoint struct { Checkpoint } -func (this *RequestUploadCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestUploadCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = "" if param == "minSize" || param == "maxSize" { value = 0 @@ -112,7 +113,7 @@ func (this *RequestUploadCheckpoint) RequestValue(req *requests.Request, param s return } -func (this *RequestUploadCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestUploadCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_uri.go b/internal/waf/checkpoints/request_uri.go index b8193f9..d927baf 100644 --- a/internal/waf/checkpoints/request_uri.go +++ b/internal/waf/checkpoints/request_uri.go @@ -2,13 +2,14 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestURICheckpoint struct { Checkpoint } -func (this *RequestURICheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestURICheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if len(req.RequestURI) > 0 { value = req.RequestURI } else if req.URL != nil { @@ -17,7 +18,7 @@ func (this *RequestURICheckpoint) RequestValue(req *requests.Request, param stri return } -func (this *RequestURICheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestURICheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/request_user_agent.go b/internal/waf/checkpoints/request_user_agent.go index d75b621..407fe50 100644 --- a/internal/waf/checkpoints/request_user_agent.go +++ b/internal/waf/checkpoints/request_user_agent.go @@ -2,18 +2,19 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) type RequestUserAgentCheckpoint struct { Checkpoint } -func (this *RequestUserAgentCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestUserAgentCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = req.UserAgent() return } -func (this *RequestUserAgentCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *RequestUserAgentCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if this.IsRequest() { return this.RequestValue(req, param, options) } diff --git a/internal/waf/checkpoints/response_body.go b/internal/waf/checkpoints/response_body.go index 2f50a58..4e48dac 100644 --- a/internal/waf/checkpoints/response_body.go +++ b/internal/waf/checkpoints/response_body.go @@ -3,6 +3,7 @@ package checkpoints import ( "bytes" "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" "io/ioutil" ) @@ -15,12 +16,12 @@ func (this *ResponseBodyCheckpoint) IsRequest() bool { return false } -func (this *ResponseBodyCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseBodyCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = "" return } -func (this *ResponseBodyCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseBodyCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = "" if resp != nil && resp.Body != nil { if len(resp.BodyData) > 0 { diff --git a/internal/waf/checkpoints/response_bytes_sent.go b/internal/waf/checkpoints/response_bytes_sent.go index 4df2b3e..9461f97 100644 --- a/internal/waf/checkpoints/response_bytes_sent.go +++ b/internal/waf/checkpoints/response_bytes_sent.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) // ${bytesSent} @@ -13,12 +14,12 @@ func (this *ResponseBytesSentCheckpoint) IsRequest() bool { return false } -func (this *ResponseBytesSentCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseBytesSentCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = 0 return } -func (this *ResponseBytesSentCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseBytesSentCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = 0 if resp != nil { value = resp.ContentLength diff --git a/internal/waf/checkpoints/response_general_header_length.go b/internal/waf/checkpoints/response_general_header_length.go new file mode 100644 index 0000000..f1ef6ff --- /dev/null +++ b/internal/waf/checkpoints/response_general_header_length.go @@ -0,0 +1,45 @@ +package checkpoints + +import ( + "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" + "github.com/iwind/TeaGo/types" +) + +type ResponseGeneralHeaderLengthCheckpoint struct { + Checkpoint +} + +func (this *ResponseGeneralHeaderLengthCheckpoint) IsRequest() bool { + return false +} + +func (this *ResponseGeneralHeaderLengthCheckpoint) IsComposed() bool { + return true +} + +func (this *ResponseGeneralHeaderLengthCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { + + return +} + +func (this *ResponseGeneralHeaderLengthCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { + value = false + + headers := options.GetSlice("headers") + if len(headers) == 0 { + return + } + + length := options.GetInt("length") + + for _, header := range headers { + v := req.Header.Get(types.String(header)) + if len(v) > length { + value = true + break + } + } + + return +} diff --git a/internal/waf/checkpoints/response_header.go b/internal/waf/checkpoints/response_header.go index 4db9150..5d23df5 100644 --- a/internal/waf/checkpoints/response_header.go +++ b/internal/waf/checkpoints/response_header.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) // ${responseHeader.arg} @@ -13,12 +14,12 @@ func (this *ResponseHeaderCheckpoint) IsRequest() bool { return false } -func (this *ResponseHeaderCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseHeaderCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = "" return } -func (this *ResponseHeaderCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseHeaderCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if resp != nil && resp.Header != nil { value = resp.Header.Get(param) } else { diff --git a/internal/waf/checkpoints/response_status.go b/internal/waf/checkpoints/response_status.go index f35870f..fb63a79 100644 --- a/internal/waf/checkpoints/response_status.go +++ b/internal/waf/checkpoints/response_status.go @@ -2,6 +2,7 @@ package checkpoints import ( "github.com/TeaOSLab/EdgeNode/internal/waf/requests" + "github.com/iwind/TeaGo/maps" ) // ${bytesSent} @@ -13,12 +14,12 @@ func (this *ResponseStatusCheckpoint) IsRequest() bool { return false } -func (this *ResponseStatusCheckpoint) RequestValue(req *requests.Request, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseStatusCheckpoint) RequestValue(req *requests.Request, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { value = 0 return } -func (this *ResponseStatusCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options map[string]interface{}) (value interface{}, sysErr error, userErr error) { +func (this *ResponseStatusCheckpoint) ResponseValue(req *requests.Request, resp *requests.Response, param string, options maps.Map) (value interface{}, sysErr error, userErr error) { if resp != nil { value = resp.StatusCode } diff --git a/internal/waf/checkpoints/utils.go b/internal/waf/checkpoints/utils.go index b029402..e3393d7 100644 --- a/internal/waf/checkpoints/utils.go +++ b/internal/waf/checkpoints/utils.go @@ -2,6 +2,13 @@ package checkpoints // all check points list var AllCheckpoints = []*CheckpointDefinition{ + { + Name: "通用请求Header长度限制", + Prefix: "requestGeneralHeaderLength", + Description: "通用Header比如Cache-Control、Accept之类的长度限制,防止缓冲区溢出攻击", + HasParams: false, + Instance: new(RequestGeneralHeaderLengthCheckpoint), + }, { Name: "客户端地址(IP)", Prefix: "remoteAddr", @@ -184,6 +191,13 @@ var AllCheckpoints = []*CheckpointDefinition{ HasParams: true, Instance: new(CCCheckpoint), }, + { + Name: "通用响应Header长度限制", + Prefix: "responseGeneralHeaderLength", + Description: "通用Header比如Cache-Control、Accept之类的长度限制,防止缓冲区溢出攻击", + HasParams: false, + Instance: new(ResponseGeneralHeaderLengthCheckpoint), + }, { Name: "响应状态码", Prefix: "status", diff --git a/internal/waf/rule.go b/internal/waf/rule.go index 8b3fb0b..a06c769 100644 --- a/internal/waf/rule.go +++ b/internal/waf/rule.go @@ -186,6 +186,12 @@ func (this *Rule) MatchRequest(req *requests.Request) (b bool, err error) { if err != nil { return false, err } + + // if is composed checkpoint, we just returns true or false + if this.singleCheckpoint.IsComposed() { + return types.Bool(value), nil + } + return this.Test(value), nil } @@ -235,6 +241,12 @@ func (this *Rule) MatchResponse(req *requests.Request, resp *requests.Response) if err != nil { return false, err } + + // if is composed checkpoint, we just returns true or false + if this.singleCheckpoint.IsComposed() { + return types.Bool(value), nil + } + return this.Test(value), nil }