diff --git a/pkg/acquisition/modules/waap/waap.go b/pkg/acquisition/modules/waap/waap.go index 44573677f..0086c96ea 100644 --- a/pkg/acquisition/modules/waap/waap.go +++ b/pkg/acquisition/modules/waap/waap.go @@ -134,7 +134,7 @@ func (w *WaapSource) Configure(yamlConfig []byte, logger *log.Entry) error { //let's load the associated waap_config: if w.config.WaapConfigPath != "" { - waapCfg := waf.WaapConfig{} + waapCfg := waf.WaapConfig{Logger: w.logger.WithField("component", "waap_config")} err := waapCfg.Load(w.config.WaapConfigPath) if err != nil { return fmt.Errorf("unable to load waap_config : %s", err) diff --git a/pkg/waf/waap.go b/pkg/waf/waap.go index f7128e991..bd6f4b6de 100644 --- a/pkg/waf/waap.go +++ b/pkg/waf/waap.go @@ -70,17 +70,18 @@ type WaapRuntimeConfig struct { } type WaapConfig struct { - Name string `yaml:"name"` - OutOfBandRules []string `yaml:"outofband_rules"` - InBandRules []string `yaml:"inband_rules"` - DefaultRemediation string `yaml:"default_remediation"` - DefaultPassAction string `yaml:"default_pass_action"` - BlockedHTTPCode int `yaml:"blocked_http_code"` - PassedHTTPCode int `yaml:"passed_http_code"` - OnLoad []Hook `yaml:"on_load"` - PreEval []Hook `yaml:"pre_eval"` - OnMatch []Hook `yaml:"on_match"` - VariablesTracking []string `yaml:"variables_tracking"` + Name string `yaml:"name"` + OutOfBandRules []string `yaml:"outofband_rules"` + InBandRules []string `yaml:"inband_rules"` + DefaultRemediation string `yaml:"default_remediation"` + DefaultPassAction string `yaml:"default_pass_action"` + BlockedHTTPCode int `yaml:"blocked_http_code"` + PassedHTTPCode int `yaml:"passed_http_code"` + OnLoad []Hook `yaml:"on_load"` + PreEval []Hook `yaml:"pre_eval"` + OnMatch []Hook `yaml:"on_match"` + VariablesTracking []string `yaml:"variables_tracking"` + Logger *log.Entry `yaml:"-"` } func (w *WaapRuntimeConfig) ClearResponse() { @@ -93,6 +94,9 @@ func (w *WaapRuntimeConfig) ClearResponse() { } func (wc *WaapConfig) Load(file string) error { + + wc.Logger.Debugf("loading config %s", file) + yamlFile, err := os.ReadFile(file) if err != nil { return fmt.Errorf("unable to read file %s : %s", file, err) @@ -127,6 +131,7 @@ func (wc *WaapConfig) Build() (*WaapRuntimeConfig, error) { //load rules for _, rule := range wc.OutOfBandRules { + wc.Logger.Debugf("loading outofband rule %s", rule) collection, err := LoadCollection(rule) if err != nil { return nil, fmt.Errorf("unable to load outofband rule %s : %s", rule, err) @@ -135,6 +140,7 @@ func (wc *WaapConfig) Build() (*WaapRuntimeConfig, error) { } for _, rule := range wc.InBandRules { + wc.Logger.Debugf("loading inband rule %s", rule) collection, err := LoadCollection(rule) if err != nil { return nil, fmt.Errorf("unable to load inband rule %s : %s", rule, err) diff --git a/pkg/waf/waap_rules_collection.go b/pkg/waf/waap_rules_collection.go index c641a2397..fd291e29b 100644 --- a/pkg/waf/waap_rules_collection.go +++ b/pkg/waf/waap_rules_collection.go @@ -3,8 +3,11 @@ package waf import ( "fmt" "os" + "path/filepath" + "strings" corazatypes "github.com/crowdsecurity/coraza/v3/types" + "github.com/crowdsecurity/crowdsec/pkg/csconfig" "github.com/crowdsecurity/crowdsec/pkg/cwhub" "gopkg.in/yaml.v2" @@ -14,6 +17,7 @@ import ( // to be filled w/ seb update type WaapCollection struct { collectionName string + Rules []string } // to be filled w/ seb update @@ -22,14 +26,15 @@ type WaapCollectionConfig struct { Name string `yaml:"name"` SecLangFilesRules []string `yaml:"seclang_files_rules"` SecLangRules []string `yaml:"seclang_rules"` - MergedRules []string `yaml:"-"` } func LoadCollection(collection string) (WaapCollection, error) { //FIXME: do it once globally - var waapRules map[string]WaapCollectionConfig + waapRules := make(map[string]WaapCollectionConfig) + for _, hubWafRuleItem := range cwhub.GetItemMap(cwhub.WAF_RULES) { + log.Infof("loading %s", hubWafRuleItem.LocalPath) if !hubWafRuleItem.Installed { continue } @@ -50,10 +55,11 @@ func LoadCollection(collection string) (WaapCollection, error) { continue } - if rule.Type != "waap-rule" { + if rule.Type != "waf-rule" { //FIXME: rename to waap-rule when hub is properly updated log.Warnf("unexpected type %s instead of waap-rule for file %s", rule.Type, hubWafRuleItem.LocalPath) continue } + log.Infof("Adding %s to waap rules", rule.Name) waapRules[rule.Name] = rule } @@ -62,14 +68,41 @@ func LoadCollection(collection string) (WaapCollection, error) { } var loadedRule WaapCollectionConfig + var ok bool - if loadedRule, ok := waapRules[collection]; !ok { + if loadedRule, ok = waapRules[collection]; !ok { return WaapCollection{}, fmt.Errorf("no waap rules found for collection %s", collection) } - return WaapCollection{ + waapCol := WaapCollection{ collectionName: loadedRule.Name, - }, nil + } + + if loadedRule.SecLangFilesRules != nil { + for _, rulesFile := range loadedRule.SecLangFilesRules { + fullPath := filepath.Join(csconfig.DataDir, rulesFile) + c, err := os.ReadFile(fullPath) + if err != nil { + log.Errorf("unable to read file %s : %s", rulesFile, err) + continue + } + for _, line := range strings.Split(string(c), "\n") { + if strings.HasPrefix(line, "#") { + continue + } + if strings.TrimSpace(line) == "" { + continue + } + waapCol.Rules = append(waapCol.Rules, line) + } + } + } + + if loadedRule.SecLangRules != nil { + waapCol.Rules = append(waapCol.Rules, loadedRule.SecLangRules...) + } + + return waapCol, nil } func (wcc WaapCollectionConfig) LoadCollection(collection string) (WaapCollection, error) {