Skip to content

Commit

Permalink
feat(transaction): data type prediction for lazy predictions
Browse files Browse the repository at this point in the history
  • Loading branch information
jptosso committed Nov 5, 2024
1 parent dee0676 commit 35b2522
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
2 changes: 2 additions & 0 deletions internal/corazarules/rule_match.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type MatchData struct {
// Keeps track of the chain depth in which the data matched.
// Multiphase specific field
ChainLevel_ int
// Metadata of the matched data
Metadata_ types.DataMetadataList
}

var _ types.MatchData = (*MatchData)(nil)
Expand Down
84 changes: 84 additions & 0 deletions types/value_metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2023 Juan Pablo Tosso and the OWASP Coraza contributors
// SPDX-License-Identifier: Apache-2.0
package types

import "unicode"

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

const (
// ValueMetadataAlphanumeric represents an alphanumeric value.
ValueMetadataAlphanumeric ValueMetadata = 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) (ValueMetadata, bool) {
switch metadata {
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 "numeric":
return ValueMetadataNumeric, true
case "boolean":
return ValueMetadataBoolean, true
case "unicode":
return ValueMetadataUnicode, true
}
return 0, false
}

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

Check failure on line 55 in types/value_metadata.go

View workflow job for this annotation

GitHub Actions / lint

field `testedTypes` is unused (unused)
}

func (v *DataMetadataList) Test(data string, metadataType ValueMetadata) bool {
result, ok := v.metadata[metadataType]
if !ok {
// we do the analysis only once
switch metadataType {
case ValueMetadataAlphanumeric:
return v.testAlphanumeric(data)
default:
// this should not happen
return false
}
}
return result

}

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

0 comments on commit 35b2522

Please sign in to comment.