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  }