github.com/TeaOSLab/EdgeNode@v1.3.8/internal/waf/rule_set_test.go (about) 1 package waf_test 2 3 import ( 4 "bytes" 5 "github.com/TeaOSLab/EdgeNode/internal/waf" 6 "github.com/TeaOSLab/EdgeNode/internal/waf/requests" 7 "github.com/cespare/xxhash/v2" 8 "github.com/iwind/TeaGo/assert" 9 "github.com/iwind/TeaGo/maps" 10 "net/http" 11 "regexp" 12 "runtime" 13 "testing" 14 ) 15 16 func TestRuleSet_MatchRequest(t *testing.T) { 17 var set = waf.NewRuleSet() 18 set.Connector = waf.RuleConnectorAnd 19 20 set.Rules = []*waf.Rule{ 21 { 22 Param: "${arg.name}", 23 Operator: waf.RuleOperatorEqString, 24 Value: "lu", 25 }, 26 { 27 Param: "${arg.age}", 28 Operator: waf.RuleOperatorEq, 29 Value: "20", 30 }, 31 } 32 33 err := set.Init(nil) 34 if err != nil { 35 t.Fatal(err) 36 } 37 38 rawReq, err := http.NewRequest(http.MethodGet, "http://teaos.cn/hello?name=lu&age=20", nil) 39 if err != nil { 40 t.Fatal(err) 41 } 42 req := requests.NewTestRequest(rawReq) 43 t.Log(set.MatchRequest(req)) 44 } 45 46 func TestRuleSet_MatchRequest2(t *testing.T) { 47 var a = assert.NewAssertion(t) 48 49 var set = waf.NewRuleSet() 50 set.Connector = waf.RuleConnectorOr 51 52 set.Rules = []*waf.Rule{ 53 { 54 Param: "${arg.name}", 55 Operator: waf.RuleOperatorEqString, 56 Value: "lu", 57 }, 58 { 59 Param: "${arg.age}", 60 Operator: waf.RuleOperatorEq, 61 Value: "21", 62 }, 63 } 64 65 err := set.Init(nil) 66 if err != nil { 67 t.Fatal(err) 68 } 69 70 rawReq, err := http.NewRequest(http.MethodGet, "http://teaos.cn/hello?name=lu&age=20", nil) 71 if err != nil { 72 t.Fatal(err) 73 } 74 req := requests.NewTestRequest(rawReq) 75 a.IsTrue(set.MatchRequest(req)) 76 } 77 78 func TestRuleSet_MatchRequest_Allow(t *testing.T) { 79 var a = assert.NewAssertion(t) 80 81 var set = waf.NewRuleSet() 82 set.Connector = waf.RuleConnectorOr 83 84 set.Rules = []*waf.Rule{ 85 { 86 Param: "${requestPath}", 87 Operator: waf.RuleOperatorMatch, 88 Value: "hello", 89 }, 90 } 91 92 set.Actions = []*waf.ActionConfig{ 93 { 94 Code: "allow", 95 Options: maps.Map{ 96 "scope": waf.AllowScopeGroup, 97 }, 98 }, 99 } 100 101 var wafInstance = waf.NewWAF() 102 103 err := set.Init(wafInstance) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 rawReq, err := http.NewRequest(http.MethodGet, "http://teaos.cn/hello?name=lu&age=20", nil) 109 if err != nil { 110 t.Fatal(err) 111 } 112 var req = requests.NewTestRequest(rawReq) 113 b, _, err := set.MatchRequest(req) 114 if err != nil { 115 t.Fatal(err) 116 } 117 a.IsTrue(b) 118 119 var result = set.PerformActions(wafInstance, &waf.RuleGroup{}, req, nil) 120 a.IsTrue(result.IsAllowed) 121 t.Log("scope:", result.AllowScope) 122 } 123 124 func BenchmarkRuleSet_MatchRequest(b *testing.B) { 125 runtime.GOMAXPROCS(1) 126 127 var set = waf.NewRuleSet() 128 set.Connector = waf.RuleConnectorOr 129 130 set.Rules = []*waf.Rule{ 131 { 132 Param: "${requestAll}", 133 Operator: waf.RuleOperatorMatch, 134 Value: `(onmouseover|onmousemove|onmousedown|onmouseup|onerror|onload|onclick|ondblclick|onkeydown|onkeyup|onkeypress)\s*=`, 135 }, 136 { 137 Param: "${requestAll}", 138 Operator: waf.RuleOperatorMatch, 139 Value: `\b(eval|system|exec|execute|passthru|shell_exec|phpinfo)\s*\(`, 140 }, 141 { 142 Param: "${arg.name}", 143 Operator: waf.RuleOperatorEqString, 144 Value: "lu", 145 }, 146 { 147 Param: "${arg.age}", 148 Operator: waf.RuleOperatorEq, 149 Value: "21", 150 }, 151 } 152 153 err := set.Init(nil) 154 if err != nil { 155 b.Fatal(err) 156 } 157 158 rawReq, err := http.NewRequest(http.MethodPost, "http://teaos.cn/hello?name=lu&age=20", bytes.NewBuffer(bytes.Repeat([]byte("HELLO"), 1024))) 159 if err != nil { 160 b.Fatal(err) 161 } 162 req := requests.NewTestRequest(rawReq) 163 for i := 0; i < b.N; i++ { 164 _, _, _ = set.MatchRequest(req) 165 } 166 } 167 168 func BenchmarkRuleSet_MatchRequest_Regexp(b *testing.B) { 169 runtime.GOMAXPROCS(1) 170 171 var set = waf.NewRuleSet() 172 set.Connector = waf.RuleConnectorOr 173 174 set.Rules = []*waf.Rule{ 175 { 176 Param: "${requestBody}", 177 Operator: waf.RuleOperatorMatch, 178 Value: `\b(eval|system|exec|execute|passthru|shell_exec|phpinfo)\s*\(`, 179 IsCaseInsensitive: false, 180 }, 181 } 182 183 err := set.Init(nil) 184 if err != nil { 185 b.Fatal(err) 186 } 187 188 rawReq, err := http.NewRequest(http.MethodPost, "http://teaos.cn/hello?name=lu&age=20", bytes.NewBuffer(bytes.Repeat([]byte("HELLO"), 2048))) 189 if err != nil { 190 b.Fatal(err) 191 } 192 req := requests.NewTestRequest(rawReq) 193 for i := 0; i < b.N; i++ { 194 _, _, _ = set.MatchRequest(req) 195 } 196 } 197 198 func BenchmarkRuleSet_MatchRequest_Regexp2(b *testing.B) { 199 reg, err := regexp.Compile(`(?iU)\b(eval|system|exec|execute|passthru|shell_exec|phpinfo)\b`) 200 if err != nil { 201 b.Fatal(err) 202 } 203 204 buf := bytes.Repeat([]byte(" HELLO "), 10240) 205 206 for i := 0; i < b.N; i++ { 207 _ = reg.Match(buf) 208 } 209 } 210 211 func BenchmarkRuleSet_MatchRequest_Regexp3(b *testing.B) { 212 reg, err := regexp.Compile(`(?iU)^(eval|system|exec|execute|passthru|shell_exec|phpinfo)`) 213 if err != nil { 214 b.Fatal(err) 215 } 216 217 buf := bytes.Repeat([]byte(" HELLO "), 1024) 218 219 for i := 0; i < b.N; i++ { 220 _ = reg.Match(buf) 221 } 222 } 223 224 func BenchmarkHash(b *testing.B) { 225 runtime.GOMAXPROCS(1) 226 227 for i := 0; i < b.N; i++ { 228 _ = xxhash.Sum64(bytes.Repeat([]byte("HELLO"), 10240)) 229 } 230 }