mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-09 03:50:27 +08:00
WAF增加“包含XSS注入”操作符
This commit is contained in:
4
internal/waf/injectionutils/libinjection_xss.c
Normal file
4
internal/waf/injectionutils/libinjection_xss.c
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#define LIBINJECTION_VERSION "3.9.1"
|
||||||
|
|
||||||
|
#include "libinjection/src/libinjection_xss.c"
|
||||||
|
#include "libinjection/src/libinjection_html5.c"
|
||||||
@@ -6,7 +6,6 @@ package injectionutils
|
|||||||
#cgo CFLAGS: -I./libinjection/src
|
#cgo CFLAGS: -I./libinjection/src
|
||||||
|
|
||||||
#include <libinjection.h>
|
#include <libinjection.h>
|
||||||
#include <libinjection_sqli.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
@@ -27,7 +26,7 @@ func DetectSQLInjection(input string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 兼容 /PATH?URI
|
// 兼容 /PATH?URI
|
||||||
if input[0] == '/' || strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://") {
|
if (input[0] == '/' || strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://")) && len(input) < 4096 {
|
||||||
var argsIndex = strings.Index(input, "?")
|
var argsIndex = strings.Index(input, "?")
|
||||||
if argsIndex > 0 {
|
if argsIndex > 0 {
|
||||||
var args = input[argsIndex+1:]
|
var args = input[argsIndex+1:]
|
||||||
54
internal/waf/injectionutils/utils_xss.go
Normal file
54
internal/waf/injectionutils/utils_xss.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package injectionutils
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -I./libinjection/src
|
||||||
|
|
||||||
|
#include <libinjection.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DetectXSS detect XSS in string
|
||||||
|
func DetectXSS(input string) bool {
|
||||||
|
if len(input) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if detectXSSOne(input) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容 /PATH?URI
|
||||||
|
if (input[0] == '/' || strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://")) && len(input) < 4096 {
|
||||||
|
var argsIndex = strings.Index(input, "?")
|
||||||
|
if argsIndex > 0 {
|
||||||
|
var args = input[argsIndex+1:]
|
||||||
|
unescapeArgs, err := url.QueryUnescape(args)
|
||||||
|
if err == nil && args != unescapeArgs {
|
||||||
|
return detectXSSOne(args) || detectXSSOne(unescapeArgs)
|
||||||
|
} else {
|
||||||
|
return detectXSSOne(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectXSSOne(input string) bool {
|
||||||
|
if len(input) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var cInput = C.CString(input)
|
||||||
|
defer C.free(unsafe.Pointer(cInput))
|
||||||
|
|
||||||
|
return C.libinjection_xss(cInput, C.size_t(len(input))) == 1
|
||||||
|
}
|
||||||
49
internal/waf/injectionutils/utils_xss_test.go
Normal file
49
internal/waf/injectionutils/utils_xss_test.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package injectionutils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/waf/injectionutils"
|
||||||
|
"github.com/iwind/TeaGo/assert"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectXSS(t *testing.T) {
|
||||||
|
var a = assert.NewAssertion(t)
|
||||||
|
a.IsFalse(injectionutils.DetectXSS(""))
|
||||||
|
a.IsFalse(injectionutils.DetectXSS("abc"))
|
||||||
|
a.IsTrue(injectionutils.DetectXSS("<script>"))
|
||||||
|
a.IsTrue(injectionutils.DetectXSS("<link>"))
|
||||||
|
a.IsFalse(injectionutils.DetectXSS("<html><span>"))
|
||||||
|
a.IsFalse(injectionutils.DetectXSS("<script>"))
|
||||||
|
a.IsTrue(injectionutils.DetectXSS("/path?onmousedown=a"))
|
||||||
|
a.IsTrue(injectionutils.DetectXSS("/path?onkeyup=a"))
|
||||||
|
a.IsTrue(injectionutils.DetectXSS("onkeyup=a"))
|
||||||
|
a.IsTrue(injectionutils.DetectXSS("<iframe scrolling='no'>"))
|
||||||
|
a.IsFalse(injectionutils.DetectXSS("<html><body><span>RequestId: 1234567890</span></body></html>"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkDetectXSS_MISS(b *testing.B) {
|
||||||
|
b.Log(injectionutils.DetectXSS("<html><body><span>RequestId: 1234567890</span></body></html>"))
|
||||||
|
|
||||||
|
runtime.GOMAXPROCS(4)
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
_ = injectionutils.DetectXSS("<html><body><span>RequestId: 1234567890</span></body></html>")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkDetectXSS_HIT(b *testing.B) {
|
||||||
|
b.Log(injectionutils.DetectXSS("<html><body><span>RequestId: 1234567890</span><script src=\"\"></script></body></html>"))
|
||||||
|
|
||||||
|
runtime.GOMAXPROCS(4)
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
_ = injectionutils.DetectXSS("<html><body><span>RequestId: 1234567890</span><script src=\"\"></script></body></html>")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -590,6 +590,28 @@ func (this *Rule) Test(value any) bool {
|
|||||||
default:
|
default:
|
||||||
return injectionutils.DetectSQLInjection(this.stringifyValue(value))
|
return injectionutils.DetectSQLInjection(this.stringifyValue(value))
|
||||||
}
|
}
|
||||||
|
case RuleOperatorContainsXSS:
|
||||||
|
if value == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch xValue := value.(type) {
|
||||||
|
case []string:
|
||||||
|
for _, v := range xValue {
|
||||||
|
if injectionutils.DetectXSS(v) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case [][]byte:
|
||||||
|
for _, v := range xValue {
|
||||||
|
if injectionutils.DetectXSS(string(v)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
return injectionutils.DetectXSS(this.stringifyValue(value))
|
||||||
|
}
|
||||||
case RuleOperatorContainsBinary:
|
case RuleOperatorContainsBinary:
|
||||||
data, _ := base64.StdEncoding.DecodeString(this.stringifyValue(this.Value))
|
data, _ := base64.StdEncoding.DecodeString(this.stringifyValue(this.Value))
|
||||||
if this.IsCaseInsensitive {
|
if this.IsCaseInsensitive {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const (
|
|||||||
RuleOperatorContainsAllWords RuleOperator = "contains all words"
|
RuleOperatorContainsAllWords RuleOperator = "contains all words"
|
||||||
RuleOperatorNotContainsAnyWord RuleOperator = "not contains any word"
|
RuleOperatorNotContainsAnyWord RuleOperator = "not contains any word"
|
||||||
RuleOperatorContainsSQLInjection RuleOperator = "contains sql injection"
|
RuleOperatorContainsSQLInjection RuleOperator = "contains sql injection"
|
||||||
|
RuleOperatorContainsXSS RuleOperator = "contains xss"
|
||||||
RuleOperatorInIPList RuleOperator = "in ip list"
|
RuleOperatorInIPList RuleOperator = "in ip list"
|
||||||
RuleOperatorHasKey RuleOperator = "has key" // has key in slice or map
|
RuleOperatorHasKey RuleOperator = "has key" // has key in slice or map
|
||||||
RuleOperatorVersionGt RuleOperator = "version gt"
|
RuleOperatorVersionGt RuleOperator = "version gt"
|
||||||
|
|||||||
Reference in New Issue
Block a user