crowdsec/pkg/waf/waap_rules_collection.go

157 lines
3.9 KiB
Go
Raw Normal View History

2023-09-11 08:35:14 +00:00
package waf
2023-09-14 07:39:24 +00:00
import (
"os"
2023-09-14 09:18:33 +00:00
"path/filepath"
"strings"
2023-09-14 07:39:24 +00:00
corazatypes "github.com/crowdsecurity/coraza/v3/types"
2023-11-17 12:45:35 +00:00
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
2023-10-25 16:45:49 +00:00
"github.com/crowdsecurity/crowdsec/pkg/waf/waap_rule"
2023-09-14 07:39:24 +00:00
log "github.com/sirupsen/logrus"
)
2023-09-11 08:35:14 +00:00
// to be filled w/ seb update
type WaapCollection struct {
2023-09-14 07:39:24 +00:00
collectionName string
2023-09-14 09:18:33 +00:00
Rules []string
2023-09-11 08:35:14 +00:00
}
2023-10-18 15:11:43 +00:00
var WAAP_RULE = "waap-rule"
2023-09-11 08:35:14 +00:00
// to be filled w/ seb update
type WaapCollectionConfig struct {
2023-10-25 16:45:49 +00:00
Type string `yaml:"type"`
Name string `yaml:"name"`
2023-10-27 09:08:54 +00:00
Debug bool `yaml:"debug"`
2023-10-25 16:45:49 +00:00
Description string `yaml:"description"`
SecLangFilesRules []string `yaml:"seclang_files_rules"`
SecLangRules []string `yaml:"seclang_rules"`
Rules []waap_rule.CustomRule `yaml:"rules"`
2023-10-27 09:10:17 +00:00
2023-11-15 14:08:57 +00:00
Labels map[string]interface{} `yaml:"labels"` //Labels is K:V list aiming at providing context the overflow
2023-10-27 09:10:17 +00:00
Data interface{} `yaml:"data"` //Ignore it
hash string `yaml:"-"`
version string `yaml:"-"`
}
type RulesDetails struct {
LogLevel log.Level
Hash string
Version string
Name string
2023-09-11 08:35:14 +00:00
}
2023-10-27 09:10:17 +00:00
// Should it be a global ?
// Is using the id is a good idea ? might be too specific to coraza and not easily reusable
var WaapRulesDetails = make(map[int]RulesDetails)
2023-11-08 20:14:03 +00:00
func LoadCollection(pattern string) ([]WaapCollection, error) {
ret := make([]WaapCollection, 0)
2023-09-14 07:39:24 +00:00
2023-11-08 20:14:03 +00:00
for _, waapRule := range waapRules {
2023-09-14 07:39:24 +00:00
2023-11-17 12:47:05 +00:00
tmpMatch, err := exprhelpers.Match(pattern, waapRule.Name)
2023-09-14 09:18:33 +00:00
2023-11-08 20:14:03 +00:00
if err != nil {
log.Errorf("unable to match %s with %s : %s", waapRule.Name, pattern, err)
continue
}
2023-11-17 12:47:05 +00:00
matched, ok := tmpMatch.(bool)
if !ok {
log.Errorf("unable to match %s with %s : %s", waapRule.Name, pattern, err)
continue
}
if !matched {
2023-11-08 20:14:03 +00:00
continue
}
waapCol := WaapCollection{
collectionName: waapRule.Name,
}
if waapRule.SecLangFilesRules != nil {
for _, rulesFile := range waapRule.SecLangFilesRules {
fullPath := filepath.Join(hub.GetDataDir(), rulesFile)
c, err := os.ReadFile(fullPath)
if err != nil {
log.Errorf("unable to read file %s : %s", rulesFile, err)
2023-09-14 09:18:33 +00:00
continue
}
2023-11-08 20:14:03 +00:00
for _, line := range strings.Split(string(c), "\n") {
if strings.HasPrefix(line, "#") {
continue
}
if strings.TrimSpace(line) == "" {
continue
}
waapCol.Rules = append(waapCol.Rules, line)
2023-09-14 09:18:33 +00:00
}
}
}
2023-11-08 20:14:03 +00:00
if waapRule.SecLangRules != nil {
waapCol.Rules = append(waapCol.Rules, waapRule.SecLangRules...)
}
2023-09-14 09:18:33 +00:00
2023-11-08 20:14:03 +00:00
if waapRule.Rules != nil {
for _, rule := range waapRule.Rules {
strRule, rulesId, err := rule.Convert(waap_rule.ModsecurityRuleType, waapRule.Name)
if err != nil {
log.Errorf("unable to convert rule %s : %s", rule.Name, err)
return nil, err
}
log.Infof("Adding rule %s", strRule)
waapCol.Rules = append(waapCol.Rules, strRule)
//We only take the first id, as it's the one of the "main" rule
if _, ok := WaapRulesDetails[int(rulesId[0])]; !ok {
WaapRulesDetails[int(rulesId[0])] = RulesDetails{
LogLevel: log.InfoLevel,
Hash: waapRule.hash,
Version: waapRule.version,
Name: waapRule.Name,
}
} else {
log.Warnf("conflicting id %d for rule %s !", rulesId[0], rule.Name)
2023-10-27 09:10:17 +00:00
}
2023-10-27 09:17:27 +00:00
2023-11-08 20:14:03 +00:00
for _, id := range rulesId {
SetRuleDebug(int(id), waapRule.Debug)
}
2023-10-27 09:10:17 +00:00
}
2023-10-17 07:32:40 +00:00
}
2023-11-08 20:14:03 +00:00
ret = append(ret, waapCol)
2023-10-17 07:32:40 +00:00
}
2023-11-08 20:14:03 +00:00
return ret, nil
2023-09-11 08:35:14 +00:00
}
func (wcc WaapCollectionConfig) LoadCollection(collection string) (WaapCollection, error) {
return WaapCollection{}, nil
}
func (w WaapCollection) Check() error {
return nil
}
func (w WaapCollection) Eval(req ParsedRequest) (*corazatypes.Interruption, error) {
return nil, nil
}
func (w WaapCollection) GetDisplayName() string {
2023-09-14 07:39:24 +00:00
return w.collectionName
2023-09-11 08:35:14 +00:00
}
2023-09-19 11:16:33 +00:00
func (w WaapCollection) String() string {
ret := ""
for _, rule := range w.Rules {
ret += rule + "\n"
}
return ret
}