appsec renaming, part 5
This commit is contained in:
parent
2089ad6663
commit
059c0adb93
|
@ -11,9 +11,9 @@ import (
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec/appsec_rule"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf/waap_rule"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewAppsecRulesCmd() *cobra.Command {
|
func NewAppsecRulesCmd() *cobra.Command {
|
||||||
|
@ -127,7 +127,7 @@ func AppsecRulesInspectRunner(itemType hubItemType) func(cmd *cobra.Command, arg
|
||||||
hub, _ := require.Hub(csConfig, nil)
|
hub, _ := require.Hub(csConfig, nil)
|
||||||
for _, name := range args {
|
for _, name := range args {
|
||||||
hubItem := hub.GetItem(itemType.name, name)
|
hubItem := hub.GetItem(itemType.name, name)
|
||||||
appsecRule := waf.AppsecCollectionConfig{}
|
appsecRule := appsec.AppsecCollectionConfig{}
|
||||||
yamlContent, err := os.ReadFile(hubItem.State.LocalPath)
|
yamlContent, err := os.ReadFile(hubItem.State.LocalPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to read file %s : %s", hubItem.State.LocalPath, err)
|
return fmt.Errorf("unable to read file %s : %s", hubItem.State.LocalPath, err)
|
||||||
|
@ -136,7 +136,7 @@ func AppsecRulesInspectRunner(itemType hubItemType) func(cmd *cobra.Command, arg
|
||||||
return fmt.Errorf("unable to unmarshal yaml file %s : %s", hubItem.State.LocalPath, err)
|
return fmt.Errorf("unable to unmarshal yaml file %s : %s", hubItem.State.LocalPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ruleType := range waap_rule.SupportedTypes() {
|
for _, ruleType := range appsec_rule.SupportedTypes() {
|
||||||
fmt.Printf("\n%s format:\n", cases.Title(language.Und, cases.NoLower).String(ruleType))
|
fmt.Printf("\n%s format:\n", cases.Title(language.Und, cases.NoLower).String(ruleType))
|
||||||
for _, rule := range appsecRule.Rules {
|
for _, rule := range appsecRule.Rules {
|
||||||
convertedRule, _, err := rule.Convert(ruleType, appsecRule.Name)
|
convertedRule, _, err := rule.Convert(ruleType, appsecRule.Name)
|
||||||
|
|
|
@ -13,12 +13,12 @@ import (
|
||||||
"github.com/crowdsecurity/go-cs-lib/trace"
|
"github.com/crowdsecurity/go-cs-lib/trace"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition"
|
"github.com/crowdsecurity/crowdsec/pkg/acquisition"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||||
leaky "github.com/crowdsecurity/crowdsec/pkg/leakybucket"
|
leaky "github.com/crowdsecurity/crowdsec/pkg/leakybucket"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/parser"
|
"github.com/crowdsecurity/crowdsec/pkg/parser"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initCrowdsec(cConfig *csconfig.Config, hub *cwhub.Hub) (*parser.Parsers, error) {
|
func initCrowdsec(cConfig *csconfig.Config, hub *cwhub.Hub) (*parser.Parsers, error) {
|
||||||
|
@ -34,7 +34,7 @@ func initCrowdsec(cConfig *csconfig.Config, hub *cwhub.Hub) (*parser.Parsers, er
|
||||||
return nil, fmt.Errorf("while loading scenarios: %w", err)
|
return nil, fmt.Errorf("while loading scenarios: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := waf.LoadAppsecRules(hub); err != nil {
|
if err := appsec.LoadAppsecRules(hub); err != nil {
|
||||||
return nil, fmt.Errorf("while loading appsec rules: %w", err)
|
return nil, fmt.Errorf("while loading appsec rules: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ var AcquisitionSources = map[string]func() DataSource{
|
||||||
"k8s-audit": func() DataSource { return &k8sauditacquisition.KubernetesAuditSource{} },
|
"k8s-audit": func() DataSource { return &k8sauditacquisition.KubernetesAuditSource{} },
|
||||||
"loki": func() DataSource { return &lokiacquisition.LokiSource{} },
|
"loki": func() DataSource { return &lokiacquisition.LokiSource{} },
|
||||||
"s3": func() DataSource { return &s3acquisition.S3Source{} },
|
"s3": func() DataSource { return &s3acquisition.S3Source{} },
|
||||||
"waf": func() DataSource { return &appsecacquisition.AppsecSource{} },
|
"appsec": func() DataSource { return &appsecacquisition.AppsecSource{} },
|
||||||
}
|
}
|
||||||
|
|
||||||
var transformRuntimes = map[string]*vm.Program{}
|
var transformRuntimes = map[string]*vm.Program{}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
|
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/trace"
|
"github.com/crowdsecurity/go-cs-lib/trace"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -52,9 +52,9 @@ type AppsecSource struct {
|
||||||
server *http.Server
|
server *http.Server
|
||||||
addr string
|
addr string
|
||||||
outChan chan types.Event
|
outChan chan types.Event
|
||||||
InChan chan waf.ParsedRequest
|
InChan chan appsec.ParsedRequest
|
||||||
AppsecRuntime *waf.AppsecRuntimeConfig
|
AppsecRuntime *appsec.AppsecRuntimeConfig
|
||||||
AppsecConfigs map[string]waf.AppsecConfig
|
AppsecConfigs map[string]appsec.AppsecConfig
|
||||||
lapiURL string
|
lapiURL string
|
||||||
AuthCache AuthCache
|
AuthCache AuthCache
|
||||||
AppsecRunners []AppsecRunner //one for each go-routine
|
AppsecRunners []AppsecRunner //one for each go-routine
|
||||||
|
@ -119,7 +119,7 @@ func (wc *AppsecSource) UnmarshalConfig(yamlConfig []byte) error {
|
||||||
wc.config.Mode = configuration.TAIL_MODE
|
wc.config.Mode = configuration.TAIL_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
// always have at least one waf routine
|
// always have at least one appsec routine
|
||||||
if wc.config.Routines == 0 {
|
if wc.config.Routines == 0 {
|
||||||
wc.config.Routines = 1
|
wc.config.Routines = 1
|
||||||
}
|
}
|
||||||
|
@ -150,12 +150,12 @@ func (w *AppsecSource) GetAggregMetrics() []prometheus.Collector {
|
||||||
func (w *AppsecSource) Configure(yamlConfig []byte, logger *log.Entry) error {
|
func (w *AppsecSource) Configure(yamlConfig []byte, logger *log.Entry) error {
|
||||||
err := w.UnmarshalConfig(yamlConfig)
|
err := w.UnmarshalConfig(yamlConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "unable to parse waf configuration")
|
return errors.Wrap(err, "unable to parse appsec configuration")
|
||||||
}
|
}
|
||||||
w.logger = logger
|
w.logger = logger
|
||||||
w.logger.Logger.SetLevel(*w.config.LogLevel)
|
w.logger.Logger.SetLevel(*w.config.LogLevel)
|
||||||
|
|
||||||
w.logger.Tracef("WAF configuration: %+v", w.config)
|
w.logger.Tracef("Appsec configuration: %+v", w.config)
|
||||||
|
|
||||||
if w.config.AuthCacheDuration == nil {
|
if w.config.AuthCacheDuration == nil {
|
||||||
w.config.AuthCacheDuration = &DefaultAuthCacheDuration
|
w.config.AuthCacheDuration = &DefaultAuthCacheDuration
|
||||||
|
@ -169,8 +169,8 @@ func (w *AppsecSource) Configure(yamlConfig []byte, logger *log.Entry) error {
|
||||||
Handler: w.mux,
|
Handler: w.mux,
|
||||||
}
|
}
|
||||||
|
|
||||||
w.InChan = make(chan waf.ParsedRequest)
|
w.InChan = make(chan appsec.ParsedRequest)
|
||||||
appsecCfg := waf.AppsecConfig{Logger: w.logger.WithField("component", "appsec_config")}
|
appsecCfg := appsec.AppsecConfig{Logger: w.logger.WithField("component", "appsec_config")}
|
||||||
|
|
||||||
//let's load the associated appsec_config:
|
//let's load the associated appsec_config:
|
||||||
if w.config.AppsecConfigPath != "" {
|
if w.config.AppsecConfigPath != "" {
|
||||||
|
@ -317,8 +317,8 @@ func (w *AppsecSource) IsAuth(apiKey string) bool {
|
||||||
|
|
||||||
// should this be in the runner ?
|
// should this be in the runner ?
|
||||||
func (w *AppsecSource) appsecHandler(rw http.ResponseWriter, r *http.Request) {
|
func (w *AppsecSource) appsecHandler(rw http.ResponseWriter, r *http.Request) {
|
||||||
apiKey := r.Header.Get(waf.APIKeyHeaderName)
|
apiKey := r.Header.Get(appsec.APIKeyHeaderName)
|
||||||
clientIP := r.Header.Get(waf.IPHeaderName)
|
clientIP := r.Header.Get(appsec.IPHeaderName)
|
||||||
remoteIP := r.RemoteAddr
|
remoteIP := r.RemoteAddr
|
||||||
if apiKey == "" {
|
if apiKey == "" {
|
||||||
w.logger.Errorf("Unauthorized request from '%s' (real IP = %s)", remoteIP, clientIP)
|
w.logger.Errorf("Unauthorized request from '%s' (real IP = %s)", remoteIP, clientIP)
|
||||||
|
@ -339,7 +339,7 @@ func (w *AppsecSource) appsecHandler(rw http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the request only once
|
// parse the request only once
|
||||||
parsedRequest, err := waf.NewParsedRequestFromRequest(r)
|
parsedRequest, err := appsec.NewParsedRequestFromRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%s", err)
|
log.Errorf("%s", err)
|
||||||
rw.WriteHeader(http.StatusInternalServerError)
|
rw.WriteHeader(http.StatusInternalServerError)
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
|
|
||||||
"github.com/crowdsecurity/coraza/v3"
|
"github.com/crowdsecurity/coraza/v3"
|
||||||
corazatypes "github.com/crowdsecurity/coraza/v3/types"
|
corazatypes "github.com/crowdsecurity/coraza/v3/types"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/tomb.v2"
|
"gopkg.in/tomb.v2"
|
||||||
|
@ -18,9 +18,9 @@ import (
|
||||||
// that's the runtime structure of the Application security engine as seen from the acquis
|
// that's the runtime structure of the Application security engine as seen from the acquis
|
||||||
type AppsecRunner struct {
|
type AppsecRunner struct {
|
||||||
outChan chan types.Event
|
outChan chan types.Event
|
||||||
inChan chan waf.ParsedRequest
|
inChan chan appsec.ParsedRequest
|
||||||
UUID string
|
UUID string
|
||||||
AppsecRuntime *waf.AppsecRuntimeConfig //this holds the actual appsec runtime config, rules, remediations, hooks etc.
|
AppsecRuntime *appsec.AppsecRuntimeConfig //this holds the actual appsec runtime config, rules, remediations, hooks etc.
|
||||||
AppsecInbandEngine coraza.WAF
|
AppsecInbandEngine coraza.WAF
|
||||||
AppsecOutbandEngine coraza.WAF
|
AppsecOutbandEngine coraza.WAF
|
||||||
logger *log.Entry
|
logger *log.Entry
|
||||||
|
@ -44,7 +44,7 @@ func (r *AppsecRunner) Init(datadir string) error {
|
||||||
outBandLogger := r.logger.Dup().WithField("band", "outband")
|
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(inBandLogger))
|
inbandCfg := coraza.NewWAFConfig().WithDirectives(inBandRules).WithRootFS(fs).WithDebugLogger(appsec.NewCrzLogger(inBandLogger))
|
||||||
if !r.AppsecRuntime.Config.InbandOptions.DisableBodyInspection {
|
if !r.AppsecRuntime.Config.InbandOptions.DisableBodyInspection {
|
||||||
inbandCfg = inbandCfg.WithRequestBodyAccess()
|
inbandCfg = inbandCfg.WithRequestBodyAccess()
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,7 @@ func (r *AppsecRunner) Init(datadir string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
//setting up outband engine
|
//setting up outband engine
|
||||||
outbandCfg := coraza.NewWAFConfig().WithDirectives(outOfBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(outBandLogger))
|
outbandCfg := coraza.NewWAFConfig().WithDirectives(outOfBandRules).WithRootFS(fs).WithDebugLogger(appsec.NewCrzLogger(outBandLogger))
|
||||||
if !r.AppsecRuntime.Config.OutOfBandOptions.DisableBodyInspection {
|
if !r.AppsecRuntime.Config.OutOfBandOptions.DisableBodyInspection {
|
||||||
outbandCfg = outbandCfg.WithRequestBodyAccess()
|
outbandCfg = outbandCfg.WithRequestBodyAccess()
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,7 +101,7 @@ func (r *AppsecRunner) Init(datadir string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) processRequest(tx waf.ExtendedTransaction, request *waf.ParsedRequest) error {
|
func (r *AppsecRunner) processRequest(tx appsec.ExtendedTransaction, request *appsec.ParsedRequest) error {
|
||||||
var in *corazatypes.Interruption
|
var in *corazatypes.Interruption
|
||||||
var err error
|
var err error
|
||||||
request.Tx = tx
|
request.Tx = tx
|
||||||
|
@ -185,21 +185,21 @@ func (r *AppsecRunner) processRequest(tx waf.ExtendedTransaction, request *waf.P
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) ProcessInBandRules(request *waf.ParsedRequest) error {
|
func (r *AppsecRunner) ProcessInBandRules(request *appsec.ParsedRequest) error {
|
||||||
tx := waf.NewExtendedTransaction(r.AppsecInbandEngine, request.UUID)
|
tx := appsec.NewExtendedTransaction(r.AppsecInbandEngine, request.UUID)
|
||||||
r.AppsecRuntime.InBandTx = tx
|
r.AppsecRuntime.InBandTx = tx
|
||||||
err := r.processRequest(tx, request)
|
err := r.processRequest(tx, request)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) ProcessOutOfBandRules(request *waf.ParsedRequest) error {
|
func (r *AppsecRunner) ProcessOutOfBandRules(request *appsec.ParsedRequest) error {
|
||||||
tx := waf.NewExtendedTransaction(r.AppsecOutbandEngine, request.UUID)
|
tx := appsec.NewExtendedTransaction(r.AppsecOutbandEngine, request.UUID)
|
||||||
r.AppsecRuntime.OutOfBandTx = tx
|
r.AppsecRuntime.OutOfBandTx = tx
|
||||||
err := r.processRequest(tx, request)
|
err := r.processRequest(tx, request)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) handleInBandInterrupt(request *waf.ParsedRequest) {
|
func (r *AppsecRunner) handleInBandInterrupt(request *appsec.ParsedRequest) {
|
||||||
//create the associated event for crowdsec itself
|
//create the associated event for crowdsec itself
|
||||||
evt, err := EventFromRequest(request)
|
evt, err := EventFromRequest(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -248,7 +248,7 @@ func (r *AppsecRunner) handleInBandInterrupt(request *waf.ParsedRequest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) handleOutBandInterrupt(request *waf.ParsedRequest) {
|
func (r *AppsecRunner) handleOutBandInterrupt(request *appsec.ParsedRequest) {
|
||||||
evt, err := EventFromRequest(request)
|
evt, err := EventFromRequest(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//let's not interrupt the pipeline for this
|
//let's not interrupt the pipeline for this
|
||||||
|
@ -284,7 +284,7 @@ func (r *AppsecRunner) handleOutBandInterrupt(request *waf.ParsedRequest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) handleRequest(request *waf.ParsedRequest) {
|
func (r *AppsecRunner) handleRequest(request *appsec.ParsedRequest) {
|
||||||
r.logger.Debugf("Requests handled by runner %s", request.UUID)
|
r.logger.Debugf("Requests handled by runner %s", request.UUID)
|
||||||
r.AppsecRuntime.ClearResponse()
|
r.AppsecRuntime.ClearResponse()
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ func (r *AppsecRunner) Run(t *tomb.Tomb) error {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-t.Dying():
|
case <-t.Dying():
|
||||||
r.logger.Infof("Waf Runner is dying")
|
r.logger.Infof("Appsec Runner is dying")
|
||||||
return nil
|
return nil
|
||||||
case request := <-r.inChan:
|
case request := <-r.inChan:
|
||||||
r.handleRequest(&request)
|
r.handleRequest(&request)
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
|
|
||||||
"github.com/crowdsecurity/coraza/v3/collection"
|
"github.com/crowdsecurity/coraza/v3/collection"
|
||||||
"github.com/crowdsecurity/coraza/v3/types/variables"
|
"github.com/crowdsecurity/coraza/v3/types/variables"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/ptr"
|
"github.com/crowdsecurity/go-cs-lib/ptr"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -51,7 +51,7 @@ func AppsecEventGeneration(inEvt types.Event) (*types.Event, error) {
|
||||||
alert.Meta = append(alert.Meta, &meta)
|
alert.Meta = append(alert.Meta, &meta)
|
||||||
}
|
}
|
||||||
alert.EventsCount = ptr.Of(int32(1))
|
alert.EventsCount = ptr.Of(int32(1))
|
||||||
alert.Labels = []string{"waf"} //don't know what to do about this
|
alert.Labels = []string{"appsec"} //don't know what to do about this
|
||||||
alert.Leakspeed = ptr.Of("")
|
alert.Leakspeed = ptr.Of("")
|
||||||
msg := fmt.Sprintf("Application Security Engine alert: %s", inEvt.Waap.MatchedRules.GetName())
|
msg := fmt.Sprintf("Application Security Engine alert: %s", inEvt.Waap.MatchedRules.GetName())
|
||||||
alert.Message = &msg
|
alert.Message = &msg
|
||||||
|
@ -68,7 +68,7 @@ func AppsecEventGeneration(inEvt types.Event) (*types.Event, error) {
|
||||||
return &evt, nil
|
return &evt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func EventFromRequest(r *waf.ParsedRequest) (types.Event, error) {
|
func EventFromRequest(r *appsec.ParsedRequest) (types.Event, error) {
|
||||||
evt := types.Event{}
|
evt := types.Event{}
|
||||||
//we might want to change this based on in-band vs out-of-band ?
|
//we might want to change this based on in-band vs out-of-band ?
|
||||||
evt.Type = types.LOG
|
evt.Type = types.LOG
|
||||||
|
@ -91,11 +91,11 @@ func EventFromRequest(r *waf.ParsedRequest) (types.Event, error) {
|
||||||
evt.Line = types.Line{
|
evt.Line = types.Line{
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
//should we add some info like listen addr/port/path ?
|
//should we add some info like listen addr/port/path ?
|
||||||
Labels: map[string]string{"type": "crowdsec-waap"}, //FIXME: use the labels from the acquis
|
Labels: map[string]string{"type": "crowdsec-appsec"}, //FIXME: use the labels from the acquis
|
||||||
Process: true,
|
Process: true,
|
||||||
Module: "appsec",
|
Module: "appsec",
|
||||||
Src: "appsec",
|
Src: "appsec",
|
||||||
Raw: "dummy-waap-data", //we discard empty Line.Raw items :)
|
Raw: "dummy-appsec-data", //we discard empty Line.Raw items :)
|
||||||
}
|
}
|
||||||
evt.Waap = types.AppsecEvent{}
|
evt.Waap = types.AppsecEvent{}
|
||||||
|
|
||||||
|
@ -110,19 +110,19 @@ func LogAppsecEvent(evt *types.Event, logger *log.Entry) {
|
||||||
|
|
||||||
if evt.Meta["waap_interrupted"] == "true" {
|
if evt.Meta["waap_interrupted"] == "true" {
|
||||||
logger.WithFields(log.Fields{
|
logger.WithFields(log.Fields{
|
||||||
"module": "waf",
|
"module": "appsec",
|
||||||
"source": evt.Parsed["source_ip"],
|
"source": evt.Parsed["source_ip"],
|
||||||
"target_uri": req,
|
"target_uri": req,
|
||||||
}).Infof("%s blocked on %s (%d rules) [%v]", evt.Parsed["source_ip"], req, len(evt.Waap.MatchedRules), evt.Waap.GetRuleIDs())
|
}).Infof("%s blocked on %s (%d rules) [%v]", evt.Parsed["source_ip"], req, len(evt.Waap.MatchedRules), evt.Waap.GetRuleIDs())
|
||||||
} else if evt.Parsed["outofband_interrupted"] == "true" {
|
} else if evt.Parsed["outofband_interrupted"] == "true" {
|
||||||
logger.WithFields(log.Fields{
|
logger.WithFields(log.Fields{
|
||||||
"module": "waf",
|
"module": "appsec",
|
||||||
"source": evt.Parsed["source_ip"],
|
"source": evt.Parsed["source_ip"],
|
||||||
"target_uri": req,
|
"target_uri": req,
|
||||||
}).Infof("%s out-of-band blocking rules on %s (%d rules) [%v]", evt.Parsed["source_ip"], req, len(evt.Waap.MatchedRules), evt.Waap.GetRuleIDs())
|
}).Infof("%s out-of-band blocking rules on %s (%d rules) [%v]", evt.Parsed["source_ip"], req, len(evt.Waap.MatchedRules), evt.Waap.GetRuleIDs())
|
||||||
} else {
|
} else {
|
||||||
logger.WithFields(log.Fields{
|
logger.WithFields(log.Fields{
|
||||||
"module": "waf",
|
"module": "appsec",
|
||||||
"source": evt.Parsed["source_ip"],
|
"source": evt.Parsed["source_ip"],
|
||||||
"target_uri": req,
|
"target_uri": req,
|
||||||
}).Debugf("%s triggered non-blocking rules on %s (%d rules) [%v]", evt.Parsed["source_ip"], req, len(evt.Waap.MatchedRules), evt.Waap.GetRuleIDs())
|
}).Debugf("%s triggered non-blocking rules on %s (%d rules) [%v]", evt.Parsed["source_ip"], req, len(evt.Waap.MatchedRules), evt.Waap.GetRuleIDs())
|
||||||
|
@ -130,7 +130,7 @@ func LogAppsecEvent(evt *types.Event, logger *log.Entry) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AppsecRunner) AccumulateTxToEvent(evt *types.Event, req *waf.ParsedRequest) error {
|
func (r *AppsecRunner) AccumulateTxToEvent(evt *types.Event, req *appsec.ParsedRequest) error {
|
||||||
|
|
||||||
if evt == nil {
|
if evt == nil {
|
||||||
//an error was already emitted, let's not spam the logs
|
//an error was already emitted, let's not spam the logs
|
||||||
|
@ -206,7 +206,7 @@ func (r *AppsecRunner) AccumulateTxToEvent(evt *types.Event, req *waf.ParsedRequ
|
||||||
hash := "NOT_SET"
|
hash := "NOT_SET"
|
||||||
ruleNameProm := fmt.Sprintf("%d", rule.Rule().ID())
|
ruleNameProm := fmt.Sprintf("%d", rule.Rule().ID())
|
||||||
|
|
||||||
if details, ok := waf.AppsecRulesDetails[rule.Rule().ID()]; ok {
|
if details, ok := appsec.AppsecRulesDetails[rule.Rule().ID()]; ok {
|
||||||
//Only set them for custom rules, not for rules written in seclang
|
//Only set them for custom rules, not for rules written in seclang
|
||||||
name = details.Name
|
name = details.Name
|
||||||
version = details.Version
|
version = details.Version
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package waap_rule
|
package appsec_rule
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package waap_rule
|
package appsec_rule
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -50,9 +50,9 @@ var bodyTypeMatch map[string]string = map[string]string{
|
||||||
"urlencoded": "URLENCODED",
|
"urlencoded": "URLENCODED",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModsecurityRule) Build(rule *CustomRule, waapRuleName string) (string, []uint32, error) {
|
func (m *ModsecurityRule) Build(rule *CustomRule, appsecRuleName string) (string, []uint32, error) {
|
||||||
|
|
||||||
rules, err := m.buildRules(rule, waapRuleName, false, 0, 0)
|
rules, err := m.buildRules(rule, appsecRuleName, false, 0, 0)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
|
@ -62,9 +62,9 @@ func (m *ModsecurityRule) Build(rule *CustomRule, waapRuleName string) (string,
|
||||||
return strings.Join(rules, "\n"), m.ids, nil
|
return strings.Join(rules, "\n"), m.ids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModsecurityRule) generateRuleID(rule *CustomRule, waapRuleName string, depth int) uint32 {
|
func (m *ModsecurityRule) generateRuleID(rule *CustomRule, appsecRuleName string, depth int) uint32 {
|
||||||
h := fnv.New32a()
|
h := fnv.New32a()
|
||||||
h.Write([]byte(waapRuleName))
|
h.Write([]byte(appsecRuleName))
|
||||||
h.Write([]byte(rule.Match.Type))
|
h.Write([]byte(rule.Match.Type))
|
||||||
h.Write([]byte(rule.Match.Value))
|
h.Write([]byte(rule.Match.Value))
|
||||||
h.Write([]byte(fmt.Sprintf("%d", depth)))
|
h.Write([]byte(fmt.Sprintf("%d", depth)))
|
||||||
|
@ -79,7 +79,7 @@ func (m *ModsecurityRule) generateRuleID(rule *CustomRule, waapRuleName string,
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and bool, toSkip int, depth int) ([]string, error) {
|
func (m *ModsecurityRule) buildRules(rule *CustomRule, appsecRuleName string, and bool, toSkip int, depth int) ([]string, error) {
|
||||||
ret := make([]string, 0)
|
ret := make([]string, 0)
|
||||||
|
|
||||||
if len(rule.And) != 0 && len(rule.Or) != 0 {
|
if len(rule.And) != 0 && len(rule.Or) != 0 {
|
||||||
|
@ -89,9 +89,8 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and
|
||||||
if rule.And != nil {
|
if rule.And != nil {
|
||||||
for c, andRule := range rule.And {
|
for c, andRule := range rule.And {
|
||||||
depth++
|
depth++
|
||||||
//subName := fmt.Sprintf("%s_and_%d", waapRuleName, c)
|
|
||||||
lastRule := c == len(rule.And)-1 // || len(rule.Or) == 0
|
lastRule := c == len(rule.And)-1 // || len(rule.Or) == 0
|
||||||
rules, err := m.buildRules(&andRule, waapRuleName, !lastRule, 0, depth)
|
rules, err := m.buildRules(&andRule, appsecRuleName, !lastRule, 0, depth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -102,9 +101,8 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and
|
||||||
if rule.Or != nil {
|
if rule.Or != nil {
|
||||||
for c, orRule := range rule.Or {
|
for c, orRule := range rule.Or {
|
||||||
depth++
|
depth++
|
||||||
//subName := fmt.Sprintf("%s_or_%d", waapRuleName, c)
|
|
||||||
skip := len(rule.Or) - c - 1
|
skip := len(rule.Or) - c - 1
|
||||||
rules, err := m.buildRules(&orRule, waapRuleName, false, skip, depth)
|
rules, err := m.buildRules(&orRule, appsecRuleName, false, skip, depth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -147,7 +145,7 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and
|
||||||
}
|
}
|
||||||
|
|
||||||
//Should phase:2 be configurable?
|
//Should phase:2 be configurable?
|
||||||
r.WriteString(fmt.Sprintf(` "id:%d,phase:2,deny,log,msg:'%s',tag:'crowdsec-%s'`, m.generateRuleID(rule, waapRuleName, depth), waapRuleName, waapRuleName))
|
r.WriteString(fmt.Sprintf(` "id:%d,phase:2,deny,log,msg:'%s',tag:'crowdsec-%s'`, m.generateRuleID(rule, appsecRuleName, depth), appsecRuleName, appsecRuleName))
|
||||||
|
|
||||||
if rule.Transform != nil {
|
if rule.Transform != nil {
|
||||||
for _, transform := range rule.Transform {
|
for _, transform := range rule.Transform {
|
|
@ -1,4 +1,4 @@
|
||||||
package waap_rule
|
package appsec_rule
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ModsecurityRuleType = "modsecurity"
|
ModsecurityRuleType = "modsecurity"
|
|
@ -1,4 +1,4 @@
|
||||||
package waap_rule
|
package appsec_rule
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -43,7 +43,7 @@ type CustomRule struct {
|
||||||
BodyType string `yaml:"body_type,omitempty"`
|
BodyType string `yaml:"body_type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CustomRule) Convert(ruleType string, waapRuleName string) (string, []uint32, error) {
|
func (v *CustomRule) Convert(ruleType string, appsecRuleName string) (string, []uint32, error) {
|
||||||
|
|
||||||
if v.Zones == nil && v.And == nil && v.Or == nil {
|
if v.Zones == nil && v.And == nil && v.Or == nil {
|
||||||
return "", nil, fmt.Errorf("no zones defined")
|
return "", nil, fmt.Errorf("no zones defined")
|
||||||
|
@ -60,7 +60,7 @@ func (v *CustomRule) Convert(ruleType string, waapRuleName string) (string, []ui
|
||||||
switch ruleType {
|
switch ruleType {
|
||||||
case ModsecurityRuleType:
|
case ModsecurityRuleType:
|
||||||
r := ModsecurityRule{}
|
r := ModsecurityRule{}
|
||||||
return r.Build(v, waapRuleName)
|
return r.Build(v, appsecRuleName)
|
||||||
default:
|
default:
|
||||||
return "", nil, fmt.Errorf("unknown rule format '%s'", ruleType)
|
return "", nil, fmt.Errorf("unknown rule format '%s'", ruleType)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
@ -17,7 +17,6 @@ func LoadAppsecRules(hubInstance *cwhub.Hub) error {
|
||||||
hub = hubInstance
|
hub = hubInstance
|
||||||
|
|
||||||
for _, hubAppsecRuleItem := range hub.GetItemMap(cwhub.APPSEC_RULES) {
|
for _, hubAppsecRuleItem := range hub.GetItemMap(cwhub.APPSEC_RULES) {
|
||||||
//log.Infof("loading %s", hubWafRuleItem.LocalPath)
|
|
||||||
if !hubAppsecRuleItem.State.Installed {
|
if !hubAppsecRuleItem.State.Installed {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -266,7 +266,7 @@ func (r *ReqDumpFilter) ToJSON() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a ParsedRequest from a http.Request. ParsedRequest can be consumed by the Waap Engine
|
// Generate a ParsedRequest from a http.Request. ParsedRequest can be consumed by the App security Engine
|
||||||
func NewParsedRequestFromRequest(r *http.Request) (ParsedRequest, error) {
|
func NewParsedRequestFromRequest(r *http.Request) (ParsedRequest, error) {
|
||||||
var err error
|
var err error
|
||||||
body := make([]byte, 0)
|
body := make([]byte, 0)
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/crowdsecurity/coraza/v3"
|
"github.com/crowdsecurity/coraza/v3"
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,12 +1,12 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec/appsec_rule"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
|
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf/waap_rule"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,7 @@ type AppsecCollectionConfig struct {
|
||||||
Description string `yaml:"description"`
|
Description string `yaml:"description"`
|
||||||
SecLangFilesRules []string `yaml:"seclang_files_rules"`
|
SecLangFilesRules []string `yaml:"seclang_files_rules"`
|
||||||
SecLangRules []string `yaml:"seclang_rules"`
|
SecLangRules []string `yaml:"seclang_rules"`
|
||||||
Rules []waap_rule.CustomRule `yaml:"rules"`
|
Rules []appsec_rule.CustomRule `yaml:"rules"`
|
||||||
|
|
||||||
Labels map[string]interface{} `yaml:"labels"` //Labels is K:V list aiming at providing context the overflow
|
Labels map[string]interface{} `yaml:"labels"` //Labels is K:V list aiming at providing context the overflow
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ type RulesDetails struct {
|
||||||
var AppsecRulesDetails = make(map[int]RulesDetails)
|
var AppsecRulesDetails = make(map[int]RulesDetails)
|
||||||
|
|
||||||
func LoadCollection(pattern string) ([]AppsecCollection, error) {
|
func LoadCollection(pattern string) ([]AppsecCollection, error) {
|
||||||
//FIXME: have a proper logger here, inheriting from waap-config to have consistent log levels
|
//FIXME: have a proper logger here, inheriting from appsec-config to have consistent log levels
|
||||||
ret := make([]AppsecCollection, 0)
|
ret := make([]AppsecCollection, 0)
|
||||||
|
|
||||||
for _, appsecRule := range appsecRules {
|
for _, appsecRule := range appsecRules {
|
||||||
|
@ -100,7 +100,7 @@ func LoadCollection(pattern string) ([]AppsecCollection, error) {
|
||||||
|
|
||||||
if appsecRule.Rules != nil {
|
if appsecRule.Rules != nil {
|
||||||
for _, rule := range appsecRule.Rules {
|
for _, rule := range appsecRule.Rules {
|
||||||
strRule, rulesId, err := rule.Convert(waap_rule.ModsecurityRuleType, appsecRule.Name)
|
strRule, rulesId, err := rule.Convert(appsec_rule.ModsecurityRuleType, appsecRule.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to convert rule %s : %s", rule.Name, err)
|
log.Errorf("unable to convert rule %s : %s", rule.Name, err)
|
||||||
return nil, err
|
return nil, err
|
|
@ -1,4 +1,4 @@
|
||||||
package waf
|
package appsec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
|
@ -11,8 +11,6 @@ import (
|
||||||
"github.com/crowdsecurity/go-cs-lib/ptr"
|
"github.com/crowdsecurity/go-cs-lib/ptr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var DataDir string // FIXME: find a better way to pass this to the waf
|
|
||||||
|
|
||||||
// CrowdsecServiceCfg contains the location of parsers/scenarios/... and acquisition files
|
// CrowdsecServiceCfg contains the location of parsers/scenarios/... and acquisition files
|
||||||
type CrowdsecServiceCfg struct {
|
type CrowdsecServiceCfg struct {
|
||||||
Enable *bool `yaml:"enable"`
|
Enable *bool `yaml:"enable"`
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/appsec/appsec_rule"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/waf/waap_rule"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
@ -55,7 +55,7 @@ func (h *HubTest) GetAppsecCoverage() ([]Coverage, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, appsecRulesFile := range configFileData.AppsecRules {
|
for _, appsecRulesFile := range configFileData.AppsecRules {
|
||||||
appsecRuleData := &waap_rule.CustomRule{}
|
appsecRuleData := &appsec_rule.CustomRule{}
|
||||||
yamlFile, err := os.ReadFile(appsecRulesFile)
|
yamlFile, err := os.ReadFile(appsecRulesFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("unable to open appsec rule '%s': %s", appsecRulesFile, err)
|
log.Printf("unable to open appsec rule '%s': %s", appsecRulesFile, err)
|
||||||
|
|
Loading…
Reference in a new issue