up
This commit is contained in:
parent
a0b0745f9d
commit
4bfa0a7b4d
3 changed files with 235 additions and 229 deletions
|
@ -40,10 +40,11 @@ func (r *WaapRunner) Init(datadir string) error {
|
||||||
for _, collection := range r.WaapRuntime.OutOfBandRules {
|
for _, collection := range r.WaapRuntime.OutOfBandRules {
|
||||||
outOfBandRules += collection.String()
|
outOfBandRules += collection.String()
|
||||||
}
|
}
|
||||||
runnerLogger := r.logger.Dup()
|
inBandLogger := r.logger.Dup().WithField("band", "inband")
|
||||||
|
outBandLogger := r.logger.Dup().WithField("band", "outband")
|
||||||
|
|
||||||
//setting up inband engine
|
//setting up inband engine
|
||||||
inbandCfg := coraza.NewWAFConfig().WithDirectives(inBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(runnerLogger))
|
inbandCfg := coraza.NewWAFConfig().WithDirectives(inBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(inBandLogger))
|
||||||
if !r.WaapRuntime.Config.InbandOptions.DisableBodyInspection {
|
if !r.WaapRuntime.Config.InbandOptions.DisableBodyInspection {
|
||||||
inbandCfg = inbandCfg.WithRequestBodyAccess()
|
inbandCfg = inbandCfg.WithRequestBodyAccess()
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,7 +59,7 @@ func (r *WaapRunner) Init(datadir string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
//setting up outband engine
|
//setting up outband engine
|
||||||
outbandCfg := coraza.NewWAFConfig().WithDirectives(outOfBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(runnerLogger))
|
outbandCfg := coraza.NewWAFConfig().WithDirectives(outOfBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(outBandLogger))
|
||||||
if !r.WaapRuntime.Config.OutOfBandOptions.DisableBodyInspection {
|
if !r.WaapRuntime.Config.OutOfBandOptions.DisableBodyInspection {
|
||||||
outbandCfg = outbandCfg.WithRequestBodyAccess()
|
outbandCfg = outbandCfg.WithRequestBodyAccess()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -18,230 +16,6 @@ const (
|
||||||
WAAP
|
WAAP
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
1. If user triggered a rule that is for a CVE, that has high confidence and that is blocking, ban
|
|
||||||
2. If user triggered 3 distinct rules with medium confidence accross 3 different requests, ban
|
|
||||||
|
|
||||||
|
|
||||||
any(evt.Waf.ByTag("CVE"), {.confidence == "high" && .action == "block"})
|
|
||||||
|
|
||||||
len(evt.Waf.ByTagRx("*CVE*").ByConfidence("high").ByAction("block")) > 1
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
type MatchedRules []map[string]interface{}
|
|
||||||
|
|
||||||
type WaapEvent struct {
|
|
||||||
MatchedRules
|
|
||||||
Vars map[string]string
|
|
||||||
}
|
|
||||||
type Field string
|
|
||||||
|
|
||||||
func (f Field) String() string {
|
|
||||||
return fmt.Sprintf("%s", f)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
ID Field = "id"
|
|
||||||
RuleType Field = "rule_type"
|
|
||||||
Tags Field = "tags"
|
|
||||||
File Field = "file"
|
|
||||||
Confidence Field = "confidence"
|
|
||||||
Revision Field = "revision"
|
|
||||||
SecMark Field = "secmark"
|
|
||||||
Accuracy Field = "accuracy"
|
|
||||||
Msg Field = "msg"
|
|
||||||
Severity Field = "severity"
|
|
||||||
Kind Field = "kind"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (w WaapEvent) GetVar(varName string) string {
|
|
||||||
if w.Vars == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if val, ok := w.Vars[varName]; ok {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
log.Infof("var %s not found", varName, w.Vars)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
func (w MatchedRules) GetField(field Field) []interface{} {
|
|
||||||
ret := make([]interface{}, 0)
|
|
||||||
for _, rule := range w {
|
|
||||||
ret = append(ret, rule[field.String()])
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) GetURI() string {
|
|
||||||
for _, rule := range w {
|
|
||||||
return rule["uri"].(string)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) GetHash() string {
|
|
||||||
for _, rule := range w {
|
|
||||||
//@sbl : let's fix this
|
|
||||||
return rule["hash"].(string)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) GetVersion() string {
|
|
||||||
for _, rule := range w {
|
|
||||||
//@sbl : let's fix this
|
|
||||||
return rule["version"].(string)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) GetName() string {
|
|
||||||
for _, rule := range w {
|
|
||||||
//@sbl : let's fix this
|
|
||||||
return rule["name"].(string)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) GetMethod() string {
|
|
||||||
for _, rule := range w {
|
|
||||||
return rule["method"].(string)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) GetRuleIDs() []int {
|
|
||||||
ret := make([]int, 0)
|
|
||||||
for _, rule := range w {
|
|
||||||
ret = append(ret, rule["id"].(int))
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) Kinds() []string {
|
|
||||||
ret := make([]string, 0)
|
|
||||||
for _, rule := range w {
|
|
||||||
exists := false
|
|
||||||
for _, val := range ret {
|
|
||||||
if val == rule["kind"] {
|
|
||||||
exists = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !exists {
|
|
||||||
ret = append(ret, rule["kind"].(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// filters
|
|
||||||
func (w MatchedRules) ByID(id int) MatchedRules {
|
|
||||||
waap := MatchedRules{}
|
|
||||||
|
|
||||||
for _, rule := range w {
|
|
||||||
if rule["id"] == id {
|
|
||||||
waap = append(waap, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return waap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) ByKind(kind string) MatchedRules {
|
|
||||||
waap := MatchedRules{}
|
|
||||||
for _, rule := range w {
|
|
||||||
if rule["kind"] == kind {
|
|
||||||
waap = append(waap, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return waap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) ByTags(match []string) MatchedRules {
|
|
||||||
waap := MatchedRules{}
|
|
||||||
for _, rule := range w {
|
|
||||||
for _, tag := range rule["tags"].([]string) {
|
|
||||||
for _, match_tag := range match {
|
|
||||||
if tag == match_tag {
|
|
||||||
waap = append(waap, rule)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return waap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) ByTag(match string) MatchedRules {
|
|
||||||
waap := MatchedRules{}
|
|
||||||
for _, rule := range w {
|
|
||||||
for _, tag := range rule["tags"].([]string) {
|
|
||||||
if tag == match {
|
|
||||||
waap = append(waap, rule)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return waap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) ByTagRx(rx string) MatchedRules {
|
|
||||||
waap := MatchedRules{}
|
|
||||||
re := regexp.MustCompile(rx)
|
|
||||||
if re == nil {
|
|
||||||
return waap
|
|
||||||
}
|
|
||||||
for _, rule := range w {
|
|
||||||
for _, tag := range rule["tags"].([]string) {
|
|
||||||
log.Infof("ByTagRx: %s = %s -> %t", rx, tag, re.MatchString(tag))
|
|
||||||
if re.MatchString(tag) {
|
|
||||||
waap = append(waap, rule)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return waap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) ByDisruptiveness(is bool) MatchedRules {
|
|
||||||
log.Infof("%s", w)
|
|
||||||
wap := MatchedRules{}
|
|
||||||
for _, rule := range w {
|
|
||||||
if rule["disruptive"] == is {
|
|
||||||
wap = append(wap, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Infof("ByDisruptiveness(%t) -> %d", is, len(wap))
|
|
||||||
|
|
||||||
return wap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) BySeverity(severity string) MatchedRules {
|
|
||||||
wap := MatchedRules{}
|
|
||||||
for _, rule := range w {
|
|
||||||
if rule["severity"] == severity {
|
|
||||||
wap = append(wap, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Infof("BySeverity(%s) -> %d", severity, len(wap))
|
|
||||||
return wap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w MatchedRules) ByAccuracy(accuracy string) MatchedRules {
|
|
||||||
wap := MatchedRules{}
|
|
||||||
for _, rule := range w {
|
|
||||||
if rule["accuracy"] == accuracy {
|
|
||||||
wap = append(wap, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Infof("ByAccuracy(%s) -> %d", accuracy, len(wap))
|
|
||||||
return wap
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event is the structure representing a runtime event (log or overflow)
|
// Event is the structure representing a runtime event (log or overflow)
|
||||||
type Event struct {
|
type Event struct {
|
||||||
/* is it a log or an overflow */
|
/* is it a log or an overflow */
|
||||||
|
|
231
pkg/types/waap_event.go
Normal file
231
pkg/types/waap_event.go
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. If user triggered a rule that is for a CVE, that has high confidence and that is blocking, ban
|
||||||
|
2. If user triggered 3 distinct rules with medium confidence accross 3 different requests, ban
|
||||||
|
|
||||||
|
|
||||||
|
any(evt.Waf.ByTag("CVE"), {.confidence == "high" && .action == "block"})
|
||||||
|
|
||||||
|
len(evt.Waf.ByTagRx("*CVE*").ByConfidence("high").ByAction("block")) > 1
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
type MatchedRules []map[string]interface{}
|
||||||
|
|
||||||
|
type WaapEvent struct {
|
||||||
|
MatchedRules
|
||||||
|
Vars map[string]string
|
||||||
|
}
|
||||||
|
type Field string
|
||||||
|
|
||||||
|
func (f Field) String() string {
|
||||||
|
return string(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ID Field = "id"
|
||||||
|
RuleType Field = "rule_type"
|
||||||
|
Tags Field = "tags"
|
||||||
|
File Field = "file"
|
||||||
|
Confidence Field = "confidence"
|
||||||
|
Revision Field = "revision"
|
||||||
|
SecMark Field = "secmark"
|
||||||
|
Accuracy Field = "accuracy"
|
||||||
|
Msg Field = "msg"
|
||||||
|
Severity Field = "severity"
|
||||||
|
Kind Field = "kind"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (w WaapEvent) GetVar(varName string) string {
|
||||||
|
if w.Vars == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if val, ok := w.Vars[varName]; ok {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
log.Infof("var %s not found. Available variables: %+v", varName, w.Vars)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters
|
||||||
|
func (w MatchedRules) GetField(field Field) []interface{} {
|
||||||
|
ret := make([]interface{}, 0)
|
||||||
|
for _, rule := range w {
|
||||||
|
ret = append(ret, rule[field.String()])
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) GetURI() string {
|
||||||
|
for _, rule := range w {
|
||||||
|
return rule["uri"].(string)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) GetHash() string {
|
||||||
|
for _, rule := range w {
|
||||||
|
//@sbl : let's fix this
|
||||||
|
return rule["hash"].(string)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) GetVersion() string {
|
||||||
|
for _, rule := range w {
|
||||||
|
//@sbl : let's fix this
|
||||||
|
return rule["version"].(string)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) GetName() string {
|
||||||
|
for _, rule := range w {
|
||||||
|
//@sbl : let's fix this
|
||||||
|
return rule["name"].(string)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) GetMethod() string {
|
||||||
|
for _, rule := range w {
|
||||||
|
return rule["method"].(string)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) GetRuleIDs() []int {
|
||||||
|
ret := make([]int, 0)
|
||||||
|
for _, rule := range w {
|
||||||
|
ret = append(ret, rule["id"].(int))
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) Kinds() []string {
|
||||||
|
ret := make([]string, 0)
|
||||||
|
for _, rule := range w {
|
||||||
|
exists := false
|
||||||
|
for _, val := range ret {
|
||||||
|
if val == rule["kind"] {
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
ret = append(ret, rule["kind"].(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// filters
|
||||||
|
func (w MatchedRules) ByID(id int) MatchedRules {
|
||||||
|
waap := MatchedRules{}
|
||||||
|
|
||||||
|
for _, rule := range w {
|
||||||
|
if rule["id"] == id {
|
||||||
|
waap = append(waap, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return waap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) ByKind(kind string) MatchedRules {
|
||||||
|
waap := MatchedRules{}
|
||||||
|
for _, rule := range w {
|
||||||
|
if rule["kind"] == kind {
|
||||||
|
waap = append(waap, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return waap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) ByTags(match []string) MatchedRules {
|
||||||
|
waap := MatchedRules{}
|
||||||
|
for _, rule := range w {
|
||||||
|
for _, tag := range rule["tags"].([]string) {
|
||||||
|
for _, match_tag := range match {
|
||||||
|
if tag == match_tag {
|
||||||
|
waap = append(waap, rule)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return waap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) ByTag(match string) MatchedRules {
|
||||||
|
waap := MatchedRules{}
|
||||||
|
for _, rule := range w {
|
||||||
|
for _, tag := range rule["tags"].([]string) {
|
||||||
|
if tag == match {
|
||||||
|
waap = append(waap, rule)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return waap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) ByTagRx(rx string) MatchedRules {
|
||||||
|
waap := MatchedRules{}
|
||||||
|
re := regexp.MustCompile(rx)
|
||||||
|
if re == nil {
|
||||||
|
return waap
|
||||||
|
}
|
||||||
|
for _, rule := range w {
|
||||||
|
for _, tag := range rule["tags"].([]string) {
|
||||||
|
log.Infof("ByTagRx: %s = %s -> %t", rx, tag, re.MatchString(tag))
|
||||||
|
if re.MatchString(tag) {
|
||||||
|
waap = append(waap, rule)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return waap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) ByDisruptiveness(is bool) MatchedRules {
|
||||||
|
log.Infof("%s", w)
|
||||||
|
wap := MatchedRules{}
|
||||||
|
for _, rule := range w {
|
||||||
|
if rule["disruptive"] == is {
|
||||||
|
wap = append(wap, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof("ByDisruptiveness(%t) -> %d", is, len(wap))
|
||||||
|
|
||||||
|
return wap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) BySeverity(severity string) MatchedRules {
|
||||||
|
wap := MatchedRules{}
|
||||||
|
for _, rule := range w {
|
||||||
|
if rule["severity"] == severity {
|
||||||
|
wap = append(wap, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof("BySeverity(%s) -> %d", severity, len(wap))
|
||||||
|
return wap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w MatchedRules) ByAccuracy(accuracy string) MatchedRules {
|
||||||
|
wap := MatchedRules{}
|
||||||
|
for _, rule := range w {
|
||||||
|
if rule["accuracy"] == accuracy {
|
||||||
|
wap = append(wap, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof("ByAccuracy(%s) -> %d", accuracy, len(wap))
|
||||||
|
return wap
|
||||||
|
}
|
Loading…
Reference in a new issue