Skip to content

Commit c024190

Browse files
committed
document events generated by the WAF and how they can be used by scenarios
1 parent 18bd9fe commit c024190

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
---
2+
id: alerts_and_scenarios
3+
title: AppSec Alerts & Scenarios
4+
sidebar_position: 5
5+
---
6+
7+
## Generated Events Layout
8+
9+
When HTTP Requests trigger _InBand_ or _OutOfBand_ AppSec/WAF rules, an event is generated. Events can be used to create scenarios that will react (ban, alerts etc.) when AppSec/WAF rules are matched.
10+
11+
The [`crowdsecurity/appsec-logs` parser](https://app.crowdsec.net/hub/author/crowdsecurity/configurations/appsec-logs) is used to parse those events and turn them into events that are easier to process with scenarios.
12+
13+
14+
The generated event looks like:
15+
16+
- `evt.Meta.service` is set to `appsec`
17+
- `evt.Meta.log_type`:
18+
- `appsec-block` for blocked requests (_InBand_ rule matched for ex)
19+
- `appsec-info` for non-blocked reuqests that triggered _OutOfBand_ rule
20+
- `evt.Meta.source_ip` is set to the source (client) IP
21+
- `evt.Meta.target_host` is set to the FQDN if present (`Host` header in the HTTP request)
22+
- `evt.Meta.target_uri` is set to the full URI of the HTTP request
23+
- `evt.Meta.rule_name` is set to the name of the triggered rule
24+
- `evt.Meta.remediation_cmpt_ip` is set to the IP of the Remediation Component (Bouncer) that sent the HTTP request.
25+
26+
:::info
27+
The [`crowdsecurity/appsec-logs` parser](https://app.crowdsec.net/hub/author/crowdsecurity/configurations/appsec-logs) is already part of the generic AppSec/WAF collections, and doesn't have to be manually installed.
28+
:::
29+
30+
31+
## Creating Scenario Based on AppSec/WAF Events
32+
33+
### Triggering on InBand Rules
34+
35+
A simple yet effective example is the [`crowdsecurity/appsec-vpatch` scenario](https://app.crowdsec.net/hub/author/crowdsecurity/configurations/appsec-vpatch) that will ban IPs triggering two distinct _InBand_ rules:
36+
37+
```yaml title="/etc/crowdsec/scenarios/appsec-vpatch.yaml"
38+
type: leaky
39+
name: crowdsecurity/appsec-vpatch
40+
filter: "evt.Meta.log_type == 'appsec-block'"
41+
distinct: evt.Meta.rule_name
42+
leakspeed: "60s"
43+
capacity: 1
44+
groupby: evt.Meta.source_ip
45+
...
46+
```
47+
48+
:::info
49+
The [`crowdsecurity/appsec-vpatch` scenario](https://app.crowdsec.net/hub/author/crowdsecurity/configurations/appsec-vpatch) is already part of the generic AppSec/WAF collections, and doesn't have to be manually installed.
50+
:::
51+
52+
### Triggering on OutOfBand Rules
53+
54+
Let's try to solve an imaginary scenario:
55+
56+
> We want to block users enumerating some URLs (`/foobar/*`) when a specific HTTP header is set (`something: *test*`). However, we only want to block/ban users that will try to access 2 or more distinct `/foobar/*` URLs while having this header set.
57+
58+
:::info
59+
Keep in mind that _OutOfBand_ rules will generate an event instead of blocking the HTTP Request.
60+
:::
61+
62+
#### The AppSec/WAF Rule
63+
64+
This is our AppSec/WAF rule:
65+
66+
```yaml title="/etc/crowdsec/appsec-rules/foobar-access.yaml"
67+
name: crowdsecurity/foobar-access
68+
description: "Detect access to foobar files with the something header set"
69+
rules:
70+
- zones:
71+
- URI
72+
transform:
73+
- lowercase
74+
match:
75+
type: startsWith
76+
value: /foobar/
77+
- zones:
78+
- HEADERS
79+
variables:
80+
- something
81+
transform:
82+
- lowercase
83+
match:
84+
type: contains
85+
value: test
86+
```
87+
88+
Let ensure it's loaded as an _OutOfBand_ rule:
89+
90+
```yaml title="/etc/crowdsec/appsec-configs/appsec-default.yaml"
91+
name: crowdsecurity/appsec-default
92+
default_remediation: ban
93+
inband_rules:
94+
- crowdsecurity/base-config
95+
- crowdsecurity/vpatch-*
96+
- crowdsecurity/generic-*
97+
#Let's add our rule as an out-of-band rule
98+
outofband_rules:
99+
- crowdsecurity/foobar-access
100+
```
101+
102+
#### The Scenario
103+
104+
We can now create a scenario that will trigger when a single IPs triggers this rule on distinct URLs:
105+
106+
```yaml title="/etc/crowdsec/scenarios/foobar-enum.yaml"
107+
type: leaky
108+
format: 3.0
109+
name: crowdsecurity/foobar-enum
110+
description: "Ban IPs repeateadly triggering out of band rules"
111+
filter: "evt.Meta.log_type == 'appsec-info' && evt.Meta.rule_name == 'crowdsecurity/foobar-access'"
112+
distinct: evt.Meta.target_uri
113+
leakspeed: "60s"
114+
capacity: 1
115+
groupby: evt.Meta.source_ip
116+
blackhole: 1m
117+
labels:
118+
remediation: true
119+
```
120+
121+
:::info
122+
The `filter` ensures only OutOfBand 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.
123+
:::
124+
125+
#### Testing
126+
127+
Let's now test our setup:
128+
129+
```bash
130+
$ curl -I localhost/foobar/1 -H 'something: test'
131+
HTTP/1.1 404 Not Found
132+
133+
$ curl -I localhost/foobar/2 -H 'something: test'
134+
HTTP/1.1 404 Not Found
135+
136+
$ curl -I localhost/foobar/3 -H 'something: test'
137+
HTTP/1.1 403 Forbidden
138+
```
139+
140+
And CrowdSec logs will show:
141+
142+
```
143+
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
144+
INFO[2024-12-02T15:28:17+01:00] (test/crowdsec) crowdsecurity/foobar-enum by ip ::1 (/0) : 4h ban on Ip ::1
145+
```
146+
147+
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.

crowdsec-docs/sidebars.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
module.exports = {
23
// By default, Docusaurus generates a sidebar from the docs folder structure
34
//tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
@@ -760,6 +761,7 @@ module.exports = {
760761
{ type: "doc", id: "appsec/create_rules" },
761762
],
762763
},
764+
{ type: "doc", id: "appsec/alerts_and_scenarios", label: "Alerts & Scenarios" },
763765
{ type: "doc", id: "appsec/installation" },
764766
{ type: "doc", id: "appsec/protocol", label: "Communication Protocol" },
765767
{ type: "doc", id: "appsec/benchmark", label: "Benchmark" },

0 commit comments

Comments
 (0)