Skip to main content
Version: Next

AppSec Alerts & Scenarios

Generated Events Layout

HTTP requests that trigger In-Band or Out-Of-Band AppSec/WAF rules generate events. These events can trigger scenarios that react by banning or alerting when rules are matched.

The crowdsecurity/appsec-logs parser is designed as a general-purpose tool to convert events into a format that is easier to process with scenarios.

The generated event looks like this:

  • evt.Meta.service is set to appsec
  • evt.Meta.log_type:
    • appsec-block for blocked requests (In-Band rule matched, for example)
    • appsec-info for requests that triggered Out-Of-Band rule (not blocked)
  • evt.Meta.source_ip is set to the source (client) IP
  • evt.Meta.target_host is set to the FQDN if present (Host header in the HTTP request)
  • evt.Meta.target_uri is set to the complete URI of the HTTP request
  • evt.Meta.rule_name is set to the name of the triggered rule
  • evt.Meta.remediation_cmpt_ip is set to the IP of the Remediation Component (Bouncer) that sent the HTTP request.
info

The crowdsecurity/appsec-logs parser is already part of the generic AppSec/WAF collections and doesn't have to be manually installed.

Creating Scenario Based on AppSec/WAF Events

Triggering on In-Band Rules

A simple yexample is the crowdsecurity/appsec-vpatch scenario that will ban IPs triggering two distinct In-Band rules:

/etc/crowdsec/scenarios/appsec-vpatch.yaml
type: leaky
name: crowdsecurity/appsec-vpatch
filter: "evt.Meta.log_type == 'appsec-block'"
distinct: evt.Meta.rule_name
leakspeed: "60s"
capacity: 1
groupby: evt.Meta.source_ip
...
info

The crowdsecurity/appsec-vpatch scenario is already part of the generic AppSec/WAF collections, and doesn't have to be manually installed.

Triggering on Out-Of-Band Rules

Let's try to solve an imaginary scenario:

We aim to prevent users from enumerating certain URLs (specifically, those that begin with /foobar/*) when a particular HTTP header is present (something: *test*). However, we want to impose this restriction only on users attempting to access two or more distinct /foobar/* URLs while this header is set.

info

Keep in mind that Out-Of-Band rules will generate an event instead of blocking the HTTP Request.

The AppSec/WAF Rule

This is our AppSec/WAF rule:

/etc/crowdsec/appsec-rules/foobar-access.yaml
name: crowdsecurity/foobar-access
description: "Detect access to foobar files with the something header set"
rules:
- zones:
- URI
transform:
- lowercase
match:
type: startsWith
value: /foobar/
- zones:
- HEADERS
variables:
- something
transform:
- lowercase
match:
type: contains
value: test

Let ensure it's loaded as an Out-Of-Band rule, first by creating a new appsec-config:

/etc/crowdsec/appsec-configs/appsec-oob.yaml
name: crowdsecurity/appsec-oob
default_remediation: ban
#Let's add our rule as an out-of-band rule
outofband_rules:
- crowdsecurity/foobar-access

And then make sure this appsec-config is loaded:

/etc/crowdsec/acquis.d/appsec.yaml
appsec_configs:
- crowdsecurity/appsec-default
- crowdsecurity/appsec-oob
labels:
type: appsec
listen_addr: 127.0.0.1:7422
source: appsec

The Scenario

We can now create a scenario that will trigger when a single IPs triggers this rule on distinct URLs:

/etc/crowdsec/scenarios/foobar-enum.yaml
type: leaky
format: 3.0
name: crowdsecurity/foobar-enum
description: "Ban IPs repeateadly triggering out of band rules"
filter: "evt.Meta.log_type == 'appsec-info' && evt.Meta.rule_name == 'crowdsecurity/foobar-access'"
distinct: evt.Meta.target_uri
leakspeed: "60s"
capacity: 1
groupby: evt.Meta.source_ip
blackhole: 1m
labels:
remediation: true
info

The filter ensures only Out-Of-Band events generated by our scenario are picked up, while the capacity: 1 and distinct: evt.Meta.target_uri will ensure that the IP has to trigger the rule on at least 2 distinct URLs to trigger the scenario.

Testing

Let's now test our setup:

$ curl -I localhost/foobar/1 -H 'something: test'
HTTP/1.1 404 Not Found

$ curl -I localhost/foobar/2 -H 'something: test'
HTTP/1.1 404 Not Found

$ curl -I localhost/foobar/3 -H 'something: test'
HTTP/1.1 403 Forbidden

And CrowdSec logs will show:

INFO[2024-12-02T15:28:16+01:00] Ip ::1 performed 'crowdsecurity/foobar-enum' (2 events over 4.780233613s) at 2024-12-02 14:28:16.858419797 +0000 UTC 
INFO[2024-12-02T15:28:17+01:00] (test/crowdsec) crowdsecurity/foobar-enum by ip ::1 (/0) : 4h ban on Ip ::1

As expected, the first two requests were processed without being blocked. The second one triggered the scenario, resulting in the third request being blocked by the bouncer.