Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/datatype_prediction' into perftest
Browse files Browse the repository at this point in the history
  • Loading branch information
piyushroshan committed Nov 21, 2024
2 parents 7529e0b + 4914ff7 commit bcf1ece
Show file tree
Hide file tree
Showing 25 changed files with 462 additions and 55 deletions.
66 changes: 66 additions & 0 deletions experimental/collection/collection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
// SPDX-License-Identifier: Apache-2.0

package collection

import (
"regexp"

"github.com/corazawaf/coraza/v3/experimental/types"
)

// Collection are used to store VARIABLE data
// for transactions, this data structured is designed
// to store slices of data for keys
// Important: CollectionMaps ARE NOT concurrent safe
type Collection interface {
// FindAll returns matches for all the items in this Collection.
FindAll() []types.MatchData

// Name returns the name for the current CollectionMap
Name() string
}

// Single is a Collection with a single element.
type Single interface {
Collection

// Get returns the value of this Single
Get() string
}

// Keyed is a Collection with elements that can be selected by key.
type Keyed interface {
Collection

// Get returns a slice of strings for a key
Get(key string) []string

// FindRegex returns a slice of MatchData for the regex
FindRegex(key *regexp.Regexp) []types.MatchData

// FindString returns a slice of MatchData for the string
FindString(key string) []types.MatchData
}

// Map are used to store VARIABLE data
// for transactions, this data structured is designed
// to store slices of data for keys
// Important: CollectionMaps ARE NOT concurrent safe
type Map interface {
Keyed

// Add a value to some key
Add(key string, value string)

// Set will replace the key's value with this slice
Set(key string, values []string)

// SetIndex will place the value under the index
// If the index is higher than the current size of the CollectionMap
// it will be appended
SetIndex(key string, index int, value string)

// Remove deletes the key from the CollectionMap
Remove(key string)
}
2 changes: 1 addition & 1 deletion experimental/plugins/macro/macro.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"fmt"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
"github.com/corazawaf/coraza/v3/types/variables"
)
Expand Down
4 changes: 3 additions & 1 deletion experimental/plugins/plugintypes/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

package plugintypes

import "github.com/corazawaf/coraza/v3/types"
import (
"github.com/corazawaf/coraza/v3/types"
)

// Rule is a rule executed against a transaction.
type Rule interface {
Expand Down
2 changes: 1 addition & 1 deletion experimental/plugins/plugintypes/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
package plugintypes

import (
"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/debuglog"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/types/variables"
)
Expand Down
27 changes: 27 additions & 0 deletions experimental/types/rule_match.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors
// SPDX-License-Identifier: Apache-2.0

package types

import (
"github.com/corazawaf/coraza/v3/types/variables"
)

// MatchData works like VariableKey but is used for logging,
// so it contains the collection as a string, and it's value
type MatchData interface {
// Variable
Variable() variables.RuleVariable
// Key of the variable, blank if no key is required
Key() string
// Value of the current VARIABLE:KEY
Value() string
// Message is the expanded macro message
Message() string
// Data is the expanded logdata of the macro
Data() string
// Chain depth of variable match
ChainLevel() int
// Metadata of the matched data
Metadata() DataMetadataList
}
140 changes: 140 additions & 0 deletions experimental/types/value_metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright 2023 Juan Pablo Tosso and the OWASP Coraza contributors
// SPDX-License-Identifier: Apache-2.0
package types

import (
"unicode"
)

// DataMetadata is the type of metadata that a value can have.
type DataMetadata int

const (
// ValueMetadataAlphanumeric represents an alphanumeric value.
ValueMetadataAlphanumeric DataMetadata = iota
// ValueMetadataAscii represents an ASCII value.
ValueMetadataAscii
// ValueMetadataBase64 represents a base64 value.
ValueMetadataBase64
// ValueMetadataURI represents a URI value.
ValueMetadataURI
// ValueMetadataDomain represents a domain value.
ValueMetadataDomain
// ValueMetadataNumeric represents a numeric value, either integer or float.
ValueMetadataNumeric
// ValueMetadataBoolean represents a boolean value.
ValueMetadataBoolean
// ValueMetadataUnicode represents a unicode value.
ValueMetadataUnicode
)

// NewValueMetadata returns a new ValueMetadata from a string.
func NewValueMetadata(metadata string) (DataMetadata, bool) {
switch metadata {
case "numeric":
return ValueMetadataNumeric, true
case "boolean":
return ValueMetadataBoolean, true
case "alphanumeric":
return ValueMetadataAlphanumeric, true
case "ascii":
return ValueMetadataAscii, true
case "base64":
return ValueMetadataBase64, true
case "uri":
return ValueMetadataURI, true
case "domain":
return ValueMetadataDomain, true
case "unicode":
return ValueMetadataUnicode, true
}
return 0, false
}

// DataMetadataList is a list of ValueMetadata.
type DataMetadataList struct {
metadata map[DataMetadata]bool
}

func (v *DataMetadataList) Evaluate(data string) {
// we do the analysis only once
if v.metadata == nil {
v.metadata = make(map[DataMetadata]bool)
v.evaluateNumeric(data)
v.evaluateBoolean(data)
v.evaluateAlphanumeric(data)
v.evaluateAscii(data)
v.evaluateBase64(data)
// v.evaluateURI(data)
// v.evaluateDomain(data)
// v.evaluateUnicode(data)
}
}

func (v *DataMetadataList) evaluateAlphanumeric(data string) bool {
for _, c := range data {
if !unicode.IsLetter(c) && !unicode.IsNumber(c) {
v.metadata[ValueMetadataAlphanumeric] = false
break
}
}
return v.metadata[ValueMetadataAlphanumeric]
}

func (v *DataMetadataList) evaluateAscii(data string) bool {
res := true
for i := 0; i < len(data); i++ {
if data[i] > unicode.MaxASCII {
res = false
break
}
}
v.metadata[ValueMetadataAscii] = res
return res
}

func isBase64(c byte) bool {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/'
}

func (v *DataMetadataList) evaluateBase64(data string) bool {
res := true
for i := 0; i < len(data); i++ {
if !isBase64(data[i]) {
res = false
break
}
}
v.metadata[ValueMetadataBase64] = res
return res
}

func (v *DataMetadataList) evaluateNumeric(data string) bool {
res := true
for _, c := range data {
if !unicode.IsNumber(c) {
res = false
break
}
}
v.metadata[ValueMetadataNumeric] = res
return res
}

func (v *DataMetadataList) evaluateBoolean(data string) bool {
res := false
if data == "true" || data == "false" {
res = true
}
v.metadata[ValueMetadataBoolean] = res
return res
}

func (v *DataMetadataList) IsInScope(metadataTypes []DataMetadata) bool {
for _, metadataType := range metadataTypes {
if v.metadata[metadataType] {
return true
}
}
return false
}
2 changes: 1 addition & 1 deletion internal/actions/setvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strconv"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/plugins/macro"
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
"github.com/corazawaf/coraza/v3/types/variables"
Expand Down
2 changes: 1 addition & 1 deletion internal/actions/setvar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"strings"
"testing"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/debuglog"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)
Expand Down
13 changes: 13 additions & 0 deletions internal/actions/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
package actions

import (
"fmt"
"strings"

"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)
Expand All @@ -30,6 +33,16 @@ func (a *tagFn) Init(r plugintypes.RuleMetadata, data string) error {
return ErrMissingArguments
}
r.(*corazawaf.Rule).Tags_ = append(r.(*corazawaf.Rule).Tags_, data)
if strings.HasPrefix(data, "metadatafilter/") {
filters_string := strings.Split(data, "/")
filters := strings.Split(filters_string[1], ",")
for _, filter := range filters {
ok := r.(*corazawaf.Rule).AddAllowedMetadata(filter)
if ok != nil {
return fmt.Errorf("invalid metadata filter: %s", filter)
}
}
}
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions internal/collections/concat.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"regexp"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/types"
"github.com/corazawaf/coraza/v3/internal/corazarules"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/types/variables"
)

Expand Down
2 changes: 1 addition & 1 deletion internal/collections/concat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"testing"

"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/experimental/types"
"github.com/corazawaf/coraza/v3/types/variables"
)

Expand Down
4 changes: 2 additions & 2 deletions internal/collections/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"regexp"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/types"
"github.com/corazawaf/coraza/v3/internal/corazarules"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/types/variables"
)

Expand Down
4 changes: 2 additions & 2 deletions internal/collections/named.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"regexp"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/types"
"github.com/corazawaf/coraza/v3/internal/corazarules"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/types/variables"
)

Expand Down
4 changes: 2 additions & 2 deletions internal/collections/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
package collections

import (
"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/types"
)

var Noop collection.Collection = &noop{}
Expand Down
4 changes: 2 additions & 2 deletions internal/collections/single.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"fmt"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/types"
"github.com/corazawaf/coraza/v3/internal/corazarules"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/types/variables"
)

Expand Down
4 changes: 2 additions & 2 deletions internal/collections/sized.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"strconv"
"strings"

"github.com/corazawaf/coraza/v3/collection"
"github.com/corazawaf/coraza/v3/experimental/collection"
"github.com/corazawaf/coraza/v3/experimental/types"
"github.com/corazawaf/coraza/v3/internal/corazarules"
"github.com/corazawaf/coraza/v3/types"
"github.com/corazawaf/coraza/v3/types/variables"
)

Expand Down
Loading

0 comments on commit bcf1ece

Please sign in to comment.