github.com/TeaOSLab/EdgeNode@v1.3.8/internal/waf/rule_test.go (about) 1 package waf 2 3 import ( 4 "github.com/TeaOSLab/EdgeNode/internal/waf/checkpoints" 5 "github.com/TeaOSLab/EdgeNode/internal/waf/requests" 6 "github.com/iwind/TeaGo/assert" 7 "github.com/iwind/TeaGo/maps" 8 "net/http" 9 "net/url" 10 "testing" 11 ) 12 13 func TestRule_Init_Single(t *testing.T) { 14 rule := NewRule() 15 rule.Param = "${arg.name}" 16 rule.Operator = RuleOperatorEqString 17 rule.Value = "lu" 18 err := rule.Init() 19 if err != nil { 20 t.Fatal(err) 21 } 22 t.Log(rule.singleParam, rule.singleCheckpoint) 23 rawReq, err := http.NewRequest(http.MethodGet, "http://teaos.cn/hello?name=lu&age=20", nil) 24 if err != nil { 25 t.Fatal(err) 26 } 27 28 req := requests.NewTestRequest(rawReq) 29 t.Log(rule.MatchRequest(req)) 30 } 31 32 func TestRule_Init_Composite(t *testing.T) { 33 rule := NewRule() 34 rule.Param = "${arg.name} ${arg.age}" 35 rule.Operator = RuleOperatorContains 36 rule.Value = "lu" 37 err := rule.Init() 38 if err != nil { 39 t.Fatal(err) 40 } 41 t.Log(rule.singleParam, rule.singleCheckpoint) 42 43 rawReq, err := http.NewRequest(http.MethodGet, "http://teaos.cn/hello?name=lu&age=20", nil) 44 if err != nil { 45 t.Fatal(err) 46 } 47 req := requests.NewTestRequest(rawReq) 48 t.Log(rule.MatchRequest(req)) 49 } 50 51 func TestRule_Test(t *testing.T) { 52 var a = assert.NewAssertion(t) 53 54 { 55 var rule = NewRule() 56 rule.Operator = RuleOperatorGt 57 rule.Value = "123" 58 err := rule.Init() 59 if err != nil { 60 t.Fatal(err) 61 } 62 a.IsTrue(rule.Test("124")) 63 a.IsFalse(rule.Test("123")) 64 a.IsFalse(rule.Test("122")) 65 a.IsFalse(rule.Test("abcdef")) 66 } 67 68 { 69 var rule = NewRule() 70 rule.Operator = RuleOperatorGte 71 rule.Value = "123" 72 err := rule.Init() 73 if err != nil { 74 t.Fatal(err) 75 } 76 a.IsTrue(rule.Test("124")) 77 a.IsTrue(rule.Test("123")) 78 a.IsFalse(rule.Test("122")) 79 } 80 81 { 82 var rule = NewRule() 83 rule.Operator = RuleOperatorLt 84 rule.Value = "123" 85 err := rule.Init() 86 if err != nil { 87 t.Fatal(err) 88 } 89 a.IsFalse(rule.Test("124")) 90 a.IsFalse(rule.Test("123")) 91 a.IsTrue(rule.Test("122")) 92 } 93 94 { 95 var rule = NewRule() 96 rule.Operator = RuleOperatorLte 97 rule.Value = "123" 98 err := rule.Init() 99 if err != nil { 100 t.Fatal(err) 101 } 102 a.IsFalse(rule.Test("124")) 103 a.IsTrue(rule.Test("123")) 104 a.IsTrue(rule.Test("122")) 105 } 106 107 { 108 var rule = NewRule() 109 rule.Operator = RuleOperatorEq 110 rule.Value = "123" 111 err := rule.Init() 112 if err != nil { 113 t.Fatal(err) 114 } 115 a.IsFalse(rule.Test("124")) 116 a.IsTrue(rule.Test("123")) 117 a.IsFalse(rule.Test("122")) 118 } 119 120 { 121 var rule = NewRule() 122 rule.Operator = RuleOperatorNeq 123 rule.Value = "123" 124 err := rule.Init() 125 if err != nil { 126 t.Fatal(err) 127 } 128 a.IsTrue(rule.Test("124")) 129 a.IsFalse(rule.Test("123")) 130 a.IsTrue(rule.Test("122")) 131 } 132 133 { 134 var rule = NewRule() 135 rule.Operator = RuleOperatorEqString 136 rule.Value = "123" 137 err := rule.Init() 138 if err != nil { 139 t.Fatal(err) 140 } 141 a.IsFalse(rule.Test("124")) 142 a.IsTrue(rule.Test("123")) 143 a.IsFalse(rule.Test("122")) 144 } 145 146 { 147 var rule = NewRule() 148 rule.Operator = RuleOperatorEqString 149 rule.Value = "abc" 150 err := rule.Init() 151 if err != nil { 152 t.Fatal(err) 153 } 154 a.IsFalse(rule.Test("ABC")) 155 a.IsTrue(rule.Test("abc")) 156 } 157 158 { 159 var rule = NewRule() 160 rule.Operator = RuleOperatorEqString 161 rule.IsCaseInsensitive = true 162 rule.Value = "abc" 163 err := rule.Init() 164 if err != nil { 165 t.Fatal(err) 166 } 167 a.IsTrue(rule.Test("ABC")) 168 a.IsTrue(rule.Test("abc")) 169 } 170 171 { 172 var rule = NewRule() 173 rule.Operator = RuleOperatorNeqString 174 rule.Value = "abc" 175 err := rule.Init() 176 if err != nil { 177 t.Fatal(err) 178 } 179 a.IsTrue(rule.Test("124")) 180 a.IsFalse(rule.Test("abc")) 181 a.IsTrue(rule.Test("122")) 182 } 183 184 { 185 var rule = NewRule() 186 rule.Operator = RuleOperatorNeqString 187 rule.IsCaseInsensitive = true 188 rule.Value = "abc" 189 err := rule.Init() 190 if err != nil { 191 t.Fatal(err) 192 } 193 a.IsFalse(rule.Test("ABC")) 194 } 195 196 { 197 var rule = NewRule() 198 rule.Operator = RuleOperatorMatch 199 rule.Value = "^\\d+" 200 err := rule.Init() 201 if err != nil { 202 t.Fatal(err) 203 } 204 a.IsTrue(rule.Test("123")) 205 a.IsFalse(rule.Test("abc123")) 206 } 207 208 { 209 var rule = NewRule() 210 rule.Operator = RuleOperatorMatch 211 rule.Value = "^\\d+" 212 err := rule.Init() 213 if err != nil { 214 t.Fatal(err) 215 } 216 a.IsTrue(rule.Test([]byte("123"))) 217 a.IsFalse(rule.Test([]byte("abc123"))) 218 } 219 220 { 221 var rule = NewRule() 222 rule.Operator = RuleOperatorMatch 223 rule.Value = "^\\d+" 224 err := rule.Init() 225 if err != nil { 226 t.Fatal(err) 227 } 228 a.IsTrue(rule.Test([][]byte{[]byte("123"), []byte("456")})) 229 a.IsFalse(rule.Test([][]byte{[]byte("abc123")})) 230 } 231 232 { 233 var rule = NewRule() 234 rule.Operator = RuleOperatorMatch 235 rule.Value = "abc" 236 rule.IsCaseInsensitive = true 237 err := rule.Init() 238 if err != nil { 239 t.Fatal(err) 240 } 241 a.IsTrue(rule.Test("ABC")) 242 } 243 244 { 245 var rule = NewRule() 246 rule.Operator = RuleOperatorMatch 247 rule.Value = "^\\d+" 248 err := rule.Init() 249 if err != nil { 250 t.Fatal(err) 251 } 252 a.IsTrue(rule.Test([]string{"123", "456", "abc"})) 253 a.IsFalse(rule.Test([]string{"abc123"})) 254 } 255 256 { 257 var rule = NewRule() 258 rule.Operator = RuleOperatorNotMatch 259 rule.Value = "\\d+" 260 err := rule.Init() 261 if err != nil { 262 t.Fatal(err) 263 } 264 a.IsFalse(rule.Test("123")) 265 a.IsTrue(rule.Test("abc")) 266 } 267 268 { 269 var rule = NewRule() 270 rule.Operator = RuleOperatorNotMatch 271 rule.Value = "abc" 272 rule.IsCaseInsensitive = true 273 err := rule.Init() 274 if err != nil { 275 t.Fatal(err) 276 } 277 a.IsFalse(rule.Test("ABC")) 278 } 279 280 { 281 var rule = NewRule() 282 rule.Operator = RuleOperatorNotMatch 283 rule.Value = "^\\d+" 284 err := rule.Init() 285 if err != nil { 286 t.Fatal(err) 287 } 288 a.IsFalse(rule.Test([]string{"123", "456", "abc"})) 289 a.IsTrue(rule.Test([]string{"abc123"})) 290 } 291 292 { 293 var rule = NewRule() 294 rule.Operator = RuleOperatorNotMatch 295 rule.Value = "^\\d+" 296 err := rule.Init() 297 if err != nil { 298 t.Fatal(err) 299 } 300 a.IsFalse(rule.Test([][]byte{[]byte("123"), []byte("456")})) 301 a.IsFalse(rule.Test([][]byte{[]byte("123"), []byte("abc")})) 302 a.IsTrue(rule.Test([][]byte{[]byte("abc123")})) 303 } 304 305 { 306 var rule = NewRule() 307 rule.Operator = RuleOperatorMatch 308 rule.Value = "^(?i)[a-z]+$" 309 err := rule.Init() 310 if err != nil { 311 t.Fatal(err) 312 } 313 a.IsTrue(rule.Test("ABC")) 314 } 315 316 { 317 var rule = NewRule() 318 rule.Operator = RuleOperatorContains 319 rule.Value = "Hello" 320 err := rule.Init() 321 if err != nil { 322 t.Fatal(err) 323 } 324 a.IsTrue(rule.Test("Hello, World")) 325 } 326 327 { 328 var rule = NewRule() 329 rule.Operator = RuleOperatorContains 330 rule.Value = "hello" 331 rule.IsCaseInsensitive = true 332 err := rule.Init() 333 if err != nil { 334 t.Fatal(err) 335 } 336 a.IsTrue(rule.Test("Hello, World")) 337 } 338 339 { 340 var rule = NewRule() 341 rule.Operator = RuleOperatorContains 342 rule.Value = "Hello" 343 err := rule.Init() 344 if err != nil { 345 t.Fatal(err) 346 } 347 a.IsTrue(rule.Test([]string{"Hello", "World"})) 348 a.IsTrue(rule.Test(maps.Map{ 349 "a": "World", "b": "Hello", 350 })) 351 a.IsFalse(rule.Test(maps.Map{ 352 "a": "World", "b": "Hello2", 353 })) 354 } 355 356 { 357 var rule = NewRule() 358 rule.Operator = RuleOperatorNotContains 359 rule.Value = "Hello" 360 err := rule.Init() 361 if err != nil { 362 t.Fatal(err) 363 } 364 a.IsFalse(rule.Test("Hello, World")) 365 a.IsTrue(rule.Test("World")) 366 } 367 368 { 369 var rule = NewRule() 370 rule.Operator = RuleOperatorNotContains 371 rule.Value = "hello" 372 rule.IsCaseInsensitive = true 373 err := rule.Init() 374 if err != nil { 375 t.Fatal(err) 376 } 377 a.IsFalse(rule.Test("Hello, World")) 378 a.IsTrue(rule.Test("World")) 379 } 380 381 { 382 var rule = NewRule() 383 rule.Operator = RuleOperatorPrefix 384 rule.Value = "Hello" 385 err := rule.Init() 386 if err != nil { 387 t.Fatal(err) 388 } 389 a.IsTrue(rule.Test("Hello, World")) 390 a.IsFalse(rule.Test("hello")) 391 a.IsFalse(rule.Test("World, Hello")) 392 } 393 394 { 395 var rule = NewRule() 396 rule.Operator = RuleOperatorPrefix 397 rule.Value = "hello" 398 rule.IsCaseInsensitive = true 399 err := rule.Init() 400 if err != nil { 401 t.Fatal(err) 402 } 403 a.IsTrue(rule.Test("Hello, World")) 404 a.IsTrue(rule.Test("hello, World")) 405 a.IsFalse(rule.Test("hell")) 406 a.IsFalse(rule.Test("World, Hello")) 407 } 408 409 { 410 var rule = NewRule() 411 rule.Operator = RuleOperatorSuffix 412 rule.Value = "Hello" 413 err := rule.Init() 414 if err != nil { 415 t.Fatal(err) 416 } 417 a.IsFalse(rule.Test("Hello, World")) 418 a.IsTrue(rule.Test("World, Hello")) 419 } 420 421 { 422 var rule = NewRule() 423 rule.Operator = RuleOperatorSuffix 424 rule.Value = "hello" 425 rule.IsCaseInsensitive = true 426 err := rule.Init() 427 if err != nil { 428 t.Fatal(err) 429 } 430 a.IsFalse(rule.Test("Hello, World")) 431 a.IsTrue(rule.Test("Hello")) 432 a.IsFalse(rule.Test("llo")) 433 a.IsTrue(rule.Test("World, Hello")) 434 } 435 436 { 437 var rule = NewRule() 438 rule.Operator = RuleOperatorHasKey 439 rule.Value = "Hello" 440 err := rule.Init() 441 if err != nil { 442 t.Fatal(err) 443 } 444 a.IsFalse(rule.Test("Hello, World")) 445 a.IsTrue(rule.Test(maps.Map{ 446 "Hello": "World", 447 })) 448 a.IsFalse(rule.Test(maps.Map{ 449 "Hello1": "World", 450 })) 451 } 452 453 { 454 var rule = NewRule() 455 rule.Operator = RuleOperatorHasKey 456 rule.Value = "hello" 457 rule.IsCaseInsensitive = true 458 err := rule.Init() 459 if err != nil { 460 t.Fatal(err) 461 } 462 a.IsFalse(rule.Test("Hello, World")) 463 a.IsTrue(rule.Test(maps.Map{ 464 "Hello": "World", 465 })) 466 a.IsFalse(rule.Test(maps.Map{ 467 "Hello1": "World", 468 })) 469 } 470 471 { 472 var rule = NewRule() 473 rule.Operator = RuleOperatorHasKey 474 rule.Value = "3" 475 err := rule.Init() 476 if err != nil { 477 t.Fatal(err) 478 } 479 a.IsFalse(rule.Test("Hello, World")) 480 a.IsFalse(rule.Test(maps.Map{ 481 "Hello": "World", 482 })) 483 a.IsTrue(rule.Test([]int{1, 2, 3, 4})) 484 } 485 { 486 var rule = NewRule() 487 rule.Operator = RuleOperatorContainsAnyWord 488 rule.Value = "How\nare\nyou" 489 rule.IsCaseInsensitive = true 490 err := rule.Init() 491 if err != nil { 492 t.Fatal(err) 493 } 494 a.IsTrue(rule.Test("how")) 495 a.IsTrue(rule.Test("How doing")) 496 a.IsFalse(rule.Test("doing")) 497 } 498 { 499 var rule = NewRule() 500 rule.Operator = RuleOperatorContainsAllWords 501 rule.Value = "How\nare\nyou" 502 rule.IsCaseInsensitive = true 503 err := rule.Init() 504 if err != nil { 505 t.Fatal(err) 506 } 507 a.IsTrue(rule.Test("how are you")) 508 a.IsTrue(rule.Test("How are you doing")) 509 a.IsFalse(rule.Test("How are dare")) 510 } 511 { 512 var rule = NewRule() 513 rule.Operator = RuleOperatorContainsSQLInjection 514 err := rule.Init() 515 if err != nil { 516 t.Fatal(err) 517 } 518 a.IsTrue(rule.Test("id=123 OR 1=1")) 519 a.IsTrue(rule.Test("id=456 UNION SELECT")) 520 a.IsTrue(rule.Test("id=456 AND select load_file('') --")) 521 a.IsFalse(rule.Test("id=123")) 522 a.IsFalse(rule.Test("id=abc123 hello world '")) 523 } 524 } 525 526 func TestRule_MatchStar(t *testing.T) { 527 { 528 rule := NewRule() 529 rule.Operator = RuleOperatorMatch 530 rule.Value = `/\*(!|\x00)` 531 err := rule.Init() 532 if err != nil { 533 t.Fatal(err) 534 } 535 t.Log(rule.Test("/*!")) 536 t.Log(rule.Test(url.QueryEscape("/*!"))) 537 t.Log(url.QueryEscape("/*!")) 538 } 539 } 540 541 func TestRule_SetCheckpointFinder(t *testing.T) { 542 { 543 rule := NewRule() 544 rule.Param = "${arg.abc}" 545 rule.Operator = RuleOperatorMatch 546 err := rule.Init() 547 if err != nil { 548 t.Fatal(err) 549 } 550 t.Logf("%#v", rule.singleCheckpoint) 551 } 552 553 { 554 rule := NewRule() 555 rule.Param = "${arg.abc}" 556 rule.Operator = RuleOperatorMatch 557 rule.checkpointFinder = func(prefix string) checkpoints.CheckpointInterface { 558 return new(checkpoints.SampleRequestCheckpoint) 559 } 560 err := rule.Init() 561 if err != nil { 562 t.Fatal(err) 563 } 564 t.Logf("%#v", rule.singleCheckpoint) 565 } 566 } 567 568 func TestRule_Version(t *testing.T) { 569 a := assert.NewAssertion(t) 570 571 { 572 rule := Rule{ 573 Operator: RuleOperatorVersionRange, 574 Value: `1.0,1.1`, 575 } 576 a.IsNil(rule.Init()) 577 a.IsTrue(rule.Test("1.0")) 578 } 579 580 { 581 rule := Rule{ 582 Operator: RuleOperatorVersionRange, 583 Value: `1.0,`, 584 } 585 a.IsNil(rule.Init()) 586 a.IsTrue(rule.Test("1.0")) 587 } 588 589 { 590 rule := Rule{ 591 Operator: RuleOperatorVersionRange, 592 Value: `,1.1`, 593 } 594 a.IsNil(rule.Init()) 595 a.IsTrue(rule.Test("1.0")) 596 } 597 598 { 599 rule := Rule{ 600 Operator: RuleOperatorVersionRange, 601 Value: `1.0,1.1`, 602 } 603 a.IsNil(rule.Init()) 604 a.IsFalse(rule.Test("0.9")) 605 } 606 607 { 608 rule := Rule{ 609 Operator: RuleOperatorVersionRange, 610 Value: `1.0`, 611 } 612 a.IsNil(rule.Init()) 613 a.IsFalse(rule.Test("0.9")) 614 } 615 616 { 617 rule := Rule{ 618 Operator: RuleOperatorVersionRange, 619 Value: `1.0`, 620 } 621 a.IsNil(rule.Init()) 622 a.IsTrue(rule.Test("1.1")) 623 } 624 } 625 626 func TestRule_IP(t *testing.T) { 627 a := assert.NewAssertion(t) 628 629 { 630 rule := Rule{ 631 Operator: RuleOperatorEqIP, 632 Value: "hello", 633 } 634 a.IsNotNil(rule.Init()) 635 a.IsFalse(rule.Test("hello")) 636 } 637 638 { 639 rule := Rule{ 640 Operator: RuleOperatorEqIP, 641 Value: "hello", 642 } 643 a.IsNotNil(rule.Init()) 644 a.IsFalse(rule.Test("192.168.1.100")) 645 } 646 647 { 648 rule := Rule{ 649 Operator: RuleOperatorEqIP, 650 Value: "192.168.1.100", 651 } 652 a.IsNil(rule.Init()) 653 a.IsTrue(rule.Test("192.168.1.100")) 654 } 655 656 { 657 rule := Rule{ 658 Operator: RuleOperatorGtIP, 659 Value: "192.168.1.90", 660 } 661 a.IsNil(rule.Init()) 662 a.IsTrue(rule.Test("192.168.1.100")) 663 } 664 665 { 666 rule := Rule{ 667 Operator: RuleOperatorGteIP, 668 Value: "192.168.1.90", 669 } 670 a.IsNil(rule.Init()) 671 a.IsTrue(rule.Test("192.168.1.100")) 672 } 673 674 { 675 rule := Rule{ 676 Operator: RuleOperatorLtIP, 677 Value: "192.168.1.90", 678 } 679 a.IsNil(rule.Init()) 680 a.IsTrue(rule.Test("192.168.1.80")) 681 } 682 683 { 684 rule := Rule{ 685 Operator: RuleOperatorLteIP, 686 Value: "192.168.1.90", 687 } 688 a.IsNil(rule.Init()) 689 a.IsTrue(rule.Test("192.168.0.100")) 690 } 691 692 { 693 rule := Rule{ 694 Operator: RuleOperatorIPRange, 695 Value: "192.168.0.90,", 696 } 697 a.IsNil(rule.Init()) 698 a.IsFalse(rule.Test("192.168.0.100")) 699 } 700 701 { 702 rule := Rule{ 703 Operator: RuleOperatorIPRange, 704 Value: "192.168.0.90,192.168.1.100", 705 } 706 a.IsNil(rule.Init()) 707 a.IsTrue(rule.Test("192.168.0.100")) 708 } 709 710 { 711 var rule = Rule{ 712 Operator: RuleOperatorIPRange, 713 Value: ",192.168.1.100", 714 } 715 a.IsNil(rule.Init()) 716 a.IsTrue(rule.Test("192.168.0.100")) 717 } 718 719 { 720 rule := Rule{ 721 Operator: RuleOperatorIPRange, 722 Value: "192.168.0.90,192.168.1.99", 723 } 724 a.IsNil(rule.Init()) 725 a.IsFalse(rule.Test("192.168.1.100")) 726 } 727 728 { 729 rule := Rule{ 730 Operator: RuleOperatorIPRange, 731 Value: "192.168.0.90/24", 732 } 733 a.IsNil(rule.Init()) 734 a.IsFalse(rule.Test("192.168.1.100")) 735 } 736 737 { 738 rule := Rule{ 739 Operator: RuleOperatorIPRange, 740 Value: "192.168.0.90/18", 741 } 742 a.IsNil(rule.Init()) 743 a.IsTrue(rule.Test("192.168.1.100")) 744 } 745 746 { 747 rule := Rule{ 748 Operator: RuleOperatorIPRange, 749 Value: "a/18", 750 } 751 a.IsNil(rule.Init()) 752 a.IsFalse(rule.Test("192.168.1.100")) 753 } 754 755 { 756 rule := Rule{ 757 Operator: RuleOperatorIPMod10, 758 Value: "6", 759 } 760 a.IsNil(rule.Init()) 761 a.IsTrue(rule.Test("192.168.1.100")) 762 } 763 764 { 765 rule := Rule{ 766 Operator: RuleOperatorIPMod100, 767 Value: "76", 768 } 769 a.IsNil(rule.Init()) 770 a.IsTrue(rule.Test("192.168.1.100")) 771 } 772 773 { 774 rule := Rule{ 775 Operator: RuleOperatorIPMod, 776 Value: "10,6", 777 } 778 a.IsNil(rule.Init()) 779 a.IsTrue(rule.Test("192.168.1.100")) 780 } 781 782 { 783 rule := Rule{ 784 Operator: RuleOperatorNotIPRange, 785 Value: "192.168.0.90,192.168.1.100", 786 } 787 a.IsNil(rule.Init()) 788 a.IsFalse(rule.Test("192.168.0.100")) 789 } 790 { 791 rule := Rule{ 792 Operator: RuleOperatorNotIPRange, 793 Value: "192.168.0.90,192.168.1.100", 794 } 795 a.IsNil(rule.Init()) 796 a.IsTrue(rule.Test("192.168.2.100")) 797 } 798 { 799 rule := Rule{ 800 Operator: RuleOperatorNotIPRange, 801 Value: "192.168.0.90/8", 802 } 803 a.IsNil(rule.Init()) 804 a.IsFalse(rule.Test("192.168.2.100")) 805 } 806 { 807 rule := Rule{ 808 Operator: RuleOperatorNotIPRange, 809 Value: "192.168.0.90/16", 810 } 811 a.IsNil(rule.Init()) 812 a.IsTrue(rule.Test("192.169.2.100")) 813 } 814 }