WAF增加包含任一字符串、包含所有字符串操作符

This commit is contained in:
刘祥超
2023-01-06 20:07:15 +08:00
parent 8a8881ac47
commit a17878f5b2
5 changed files with 74 additions and 10 deletions

View File

@@ -49,8 +49,7 @@ type Rule struct {
ipValue net.IP ipValue net.IP
ipRangeListValue *values.IPRangeList ipRangeListValue *values.IPRangeList
numberListValue *values.NumberList stringValues []string
stringListValue *values.StringList
floatValue float64 floatValue float64
reg *re.Regexp reg *re.Regexp
@@ -75,6 +74,21 @@ func (this *Rule) Init() error {
this.floatValue = types.Float64(this.Value) this.floatValue = types.Float64(this.Value)
case RuleOperatorNeq: case RuleOperatorNeq:
this.floatValue = types.Float64(this.Value) this.floatValue = types.Float64(this.Value)
case RuleOperatorContainsAny, RuleOperatorContainsAll:
this.stringValues = []string{}
if len(this.Value) > 0 {
var lines = strings.Split(this.Value, "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if len(line) > 0 {
if this.IsCaseInsensitive {
this.stringValues = append(this.stringValues, strings.ToLower(line))
} else {
this.stringValues = append(this.stringValues, line)
}
}
}
}
case RuleOperatorMatch: case RuleOperatorMatch:
v := this.Value v := this.Value
if this.IsCaseInsensitive && !strings.HasPrefix(v, "(?i)") { if this.IsCaseInsensitive && !strings.HasPrefix(v, "(?i)") {
@@ -452,6 +466,33 @@ func (this *Rule) Test(value interface{}) bool {
} else { } else {
return strings.HasSuffix(types.String(value), this.Value) return strings.HasSuffix(types.String(value), this.Value)
} }
case RuleOperatorContainsAny:
var stringValue = types.String(value)
if this.IsCaseInsensitive {
stringValue = strings.ToLower(stringValue)
}
if len(stringValue) > 0 && len(this.stringValues) > 0 {
for _, v := range this.stringValues {
if strings.Contains(stringValue, v) {
return true
}
}
}
return false
case RuleOperatorContainsAll:
var stringValue = types.String(value)
if this.IsCaseInsensitive {
stringValue = strings.ToLower(stringValue)
}
if len(stringValue) > 0 && len(this.stringValues) > 0 {
for _, v := range this.stringValues {
if !strings.Contains(stringValue, v) {
return false
}
}
return true
}
return false
case RuleOperatorContainsBinary: case RuleOperatorContainsBinary:
data, _ := base64.StdEncoding.DecodeString(types.String(this.Value)) data, _ := base64.StdEncoding.DecodeString(types.String(this.Value))
if this.IsCaseInsensitive { if this.IsCaseInsensitive {

View File

@@ -18,6 +18,8 @@ const (
RuleOperatorNotContains RuleOperator = "not contains" RuleOperatorNotContains RuleOperator = "not contains"
RuleOperatorPrefix RuleOperator = "prefix" RuleOperatorPrefix RuleOperator = "prefix"
RuleOperatorSuffix RuleOperator = "suffix" RuleOperatorSuffix RuleOperator = "suffix"
RuleOperatorContainsAny RuleOperator = "containsAny"
RuleOperatorContainsAll RuleOperator = "containsAll"
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"
RuleOperatorVersionLt RuleOperator = "version lt" RuleOperatorVersionLt RuleOperator = "version lt"

View File

@@ -3,5 +3,5 @@
package values package values
func ParseIPList(v string) *StringList { func ParseIPList(v string) *StringList {
return ParseStringList(v) return ParseStringList(v, false)
} }

View File

@@ -9,16 +9,18 @@ import (
type StringList struct { type StringList struct {
ValueMap map[string]zero.Zero ValueMap map[string]zero.Zero
CaseInsensitive bool
} }
func NewStringList() *StringList { func NewStringList(caseInsensitive bool) *StringList {
return &StringList{ return &StringList{
ValueMap: map[string]zero.Zero{}, ValueMap: map[string]zero.Zero{},
CaseInsensitive: caseInsensitive,
} }
} }
func ParseStringList(v string) *StringList { func ParseStringList(v string, caseInsensitive bool) *StringList {
var list = NewStringList() var list = NewStringList(caseInsensitive)
if len(v) == 0 { if len(v) == 0 {
return list return list
} }
@@ -34,6 +36,9 @@ func ParseStringList(v string) *StringList {
for _, value := range values { for _, value := range values {
value = strings.TrimSpace(value) value = strings.TrimSpace(value)
if len(value) > 0 { if len(value) > 0 {
if caseInsensitive {
value = strings.ToLower(value)
}
list.ValueMap[value] = zero.Zero{} list.ValueMap[value] = zero.Zero{}
} }
} }
@@ -42,6 +47,9 @@ func ParseStringList(v string) *StringList {
} }
func (this *StringList) Contains(f string) bool { func (this *StringList) Contains(f string) bool {
if this.CaseInsensitive {
f = strings.ToLower(f)
}
_, ok := this.ValueMap[f] _, ok := this.ValueMap[f]
return ok return ok
} }

View File

@@ -12,7 +12,7 @@ func TestParseStringList(t *testing.T) {
var a = assert.NewAssertion(t) var a = assert.NewAssertion(t)
{ {
var list = values.ParseStringList("") var list = values.ParseStringList("", false)
a.IsFalse(list.Contains("hello")) a.IsFalse(list.Contains("hello"))
} }
@@ -22,9 +22,22 @@ func TestParseStringList(t *testing.T) {
world world
hi hi
people`) people`, false)
a.IsTrue(list.Contains("hello")) a.IsTrue(list.Contains("hello"))
a.IsFalse(list.Contains("hello1")) a.IsFalse(list.Contains("hello1"))
a.IsFalse(list.Contains("Hello"))
a.IsTrue(list.Contains("hi")) a.IsTrue(list.Contains("hi"))
} }
{
var list = values.ParseStringList(`Hello
world
hi
people`, true)
a.IsTrue(list.Contains("hello"))
a.IsTrue(list.Contains("Hello"))
a.IsTrue(list.Contains("HELLO"))
a.IsFalse(list.Contains("How"))
}
} }