Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions crowdsec-docs/docs/appsec/alerts_and_scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,23 @@ This is our AppSec/WAF rule:
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
- and:
- zones:
- URI
transform:
- lowercase
match:
type: startsWith
value: /foobar/
- zones:
- HEADERS
variables:
- something
transform:
- lowercase
match:
type: contains
value: test
```

Let's ensure it's loaded as an _Out-Of-Band_ rule by creating a new AppSec config:
Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/appsec/api_validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ With this configuration:
- `POST /users` with `{"username": "ab", "email": "x"}` is dropped (`username` too short, `email` malformed).
- `POST /users` with a valid body passes validation and is then evaluated by the WAF rules as usual.
- `GET /users` is dropped with reason `method_not_allowed` (default policy).
- `POST /admin` is dropped with reason `route_not_found` (default policy).
- `POST /admin` is not validated by this hook because the filter only matches `/users` paths.

## Metrics

Expand Down
12 changes: 9 additions & 3 deletions crowdsec-docs/docs/appsec/bot_detection/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ Every recipe on this page is a **complete overlay appsec-config** — a standalo
To deploy any recipe below:

1. **Save the file** to `/etc/crowdsec/appsec-configs/` — the filename is free, the `name:` inside is what identifies the config.
2. **Load it from your acquisition.** Add its `name:` to `appsec_configs:` in your AppSec datasource (typically `/etc/crowdsec/acquis.d/appsec.yaml`). A custom name in your own namespace is **not** matched by the `crowdsecurity/appsec-bot-*` wildcard from [Enable bot detection](enable.md#install-the-collection), so list it explicitly alongside the wildcard:
2. **Load it from your acquisition.** Add its `name:` to `appsec_configs:` in your AppSec datasource (typically `/etc/crowdsec/acquis.d/appsec.yaml`). A custom name in your own namespace is **not** matched by the `crowdsecurity/appsec-bot-*` wildcard from [Enable bot detection](enable.md#install-the-collection), so list it explicitly, before the wildcard:

```yaml
source: appsec
listen_addr: 127.0.0.1:7422
appsec_configs:
- crowdsecurity/appsec-bot-*
- crowdsecurity/appsec-default
- mycorp/appsec-bot-challenge-checkout-only # your overlay, by name
- crowdsecurity/appsec-bot-*
labels:
type: appsec
```
Expand Down Expand Up @@ -322,7 +324,11 @@ inband:
- SendChallenge()
```

`SendChallenge()` here re-issues the challenge even though the client has a cookie; `SetChallengeDifficulty("high")` makes the re-issued proof-of-work costly. Both helpers are available in `on_challenge` (but not in `on_challenge_submit`).
The cookie records the difficulty the client solved: `medium` by default, or whatever `SetChallengeDifficulty()` set when the challenge was issued. `SendChallenge()` does not re-challenge a client whose cookie already covers the target: if the cookie's difficulty is greater than or equal to the target, it does nothing. Called alone on a returning client, it is a no-op.

In `on_challenge`, `SetChallengeDifficulty("high")` raises the target for this request only (it doesn't change the difficulty for other clients), and must run before `SendChallenge()`. A client whose cookie proved `medium` is then re-challenged with a costlier proof-of-work. Both helpers are available in `on_challenge` (but not in `on_challenge_submit`).

This has a limit: a client that already solved at `high` (for example on a route where you raised the difficulty with the [per-route recipe](#tune-the-challenge-difficulty-per-route)) is not re-challenged. `impossible` won't help either, since it's effectively a block. For that case, use `DropRequest()`, as in the next recipe.

### Block a returning client outright on a strong signal

Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/appsec/bot_detection/enable.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ curl -i https://your-protected-site.example/some/page
# and a Set-Cookie for __crowdsec_challenge once the challenge is solved.
```

Tail the CrowdSec log and trigger a failed submission (e.g. with `curl` against `/crowdsec-internal/challenge/submit` with garbage payload) to see the `on_challenge_submit rejected` line. After enough failed submissions, the behavioral scenario should fire and appear in `cscli alerts list`.
Tail the CrowdSec log and send a garbage payload to `/crowdsec-internal/challenge/submit` (e.g. with `curl`): the response body is `{"status":"failed"}` and the log shows a `challenge validation failed: …` line at error level. To see the `on_challenge_submit rejected` line, use the CDP test below. Each failed submission creates an alert on its own (see [What the alert looks like](#what-the-alert-looks-like)). The `crowdsecurity/appsec-bot-challenge-too-many-submissions` behavioral scenario fires on more than 5 submissions within seconds, failed or not, and appears in `cscli alerts list`.

### Get rejected as a bot (CDP)

Expand Down
5 changes: 3 additions & 2 deletions crowdsec-docs/docs/appsec/bot_detection/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ This hook fires for in-band requests that carry a valid `__crowdsec_challenge` c

| Helper Name | Type | Description |
| -------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SendChallenge` | `func()` | Force a re-challenge for this request even though the client already has a cookie (e.g. when fingerprint mismatches indicate the cookie may have been replayed). |
| `SendChallenge` | `func()` | Re-challenge a cookie-bearing client; only takes effect when the target difficulty exceeds the one its cookie proved (see `SetChallengeDifficulty`). |
| `SetChallengeDifficulty` | `func(level str)` | Override the proof-of-work difficulty for the next challenge issued. See [Challenge difficulty levels](#challenge-difficulty-levels). |
| `SetRemediation` | `func(action str)` | Set the remediation returned to the bouncer for this request. The only special value is `allow` (don't block); any other value is passed through as-is. See [`SetRemediation*`](../hooks.md#setremediation). |
| `SetReturnCode` | `func(code int)` | Set the HTTP status code returned to the bouncer for this request. |
Expand All @@ -93,6 +93,7 @@ This hook fires for in-band requests that carry a valid `__crowdsec_challenge` c
on_challenge:
- filter: EvaluateMismatches().High() >= 1
apply:
- SetChallengeDifficulty("high")
- SendChallenge()
```

Expand Down Expand Up @@ -143,7 +144,7 @@ The helper describes the cookie the client **sent**, not the one it is about to
| The challenge submission itself (`/crowdsec-internal/challenge/submit`) | `false` — the success cookie is minted on the response |

:::note
You don't need this helper to avoid re-challenging a visitor: `SendChallenge()` is already a no-op for a client that holds a valid cookie or has been exempted. It is meant for the *other* decisions you may want to take differently for a client that has passed the challenge — which rules to run, how to score the request, what remediation to return.
You don't need this helper to avoid re-challenging a visitor: `SendChallenge()` is already a no-op for an exempted client, or one whose cookie proved at least the target difficulty. It is meant for the *other* decisions you may want to take differently for a client that has passed the challenge — which rules to run, how to score the request, what remediation to return.
:::

### Examples
Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/appsec/configuration_rule_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ source: appsec

If you want to ignore all rule matches for a specific IP or range, you can use a [centralized allowlist](/local_api/allowlists.md).

Rules will be processed as usual, but the request will not be blocked even if a rule matches.
The request bypasses AppSec entirely: no in-band or out-of-band rule is evaluated for that IP.

### Disable specific rules for a specific IP/range

Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/appsec/create_rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ user_id=123;cat /etc/password&do=yes

## Prerequisites

1. [Create a local test environment](https://doc.crowdsec.net/docs/contributing/contributing_test_env) or have CrowdSec (>= 1.5.6) installed locally
1. [Create a local test environment](https://doc.crowdsec.net/docs/contributing/contributing_test_env) or have CrowdSec (>= 1.6.0) installed locally
2. Have Docker installed locally to run the test web server
3. Have [Nuclei installed](https://docs.projectdiscovery.io/tools/nuclei/install) (`go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest`)
4. Clone the hub
Expand Down
6 changes: 3 additions & 3 deletions crowdsec-docs/docs/appsec/crs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Then use it in your acquisition configuration, for example `/etc/crowdsec/acquis

```yaml
source: appsec
appsec-configs:
appsec_configs:
- crowdsecurity/crs
labels:
type: appsec
Expand All @@ -58,7 +58,7 @@ Then add it to your acquisition configuration:

```yaml
source: appsec
appsec-configs:
appsec_configs:
- crowdsecurity/crs
- custom/crs-alerting
labels:
Expand All @@ -80,7 +80,7 @@ Then load it in your configuration:

```yaml
source: appsec
appsec-configs:
appsec_configs:
- crowdsecurity/crs-inband
labels:
type: appsec
Expand Down
4 changes: 2 additions & 2 deletions crowdsec-docs/docs/appsec/quickstart/general.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This guide covers the core AppSec Component setup that applies to all web server

## Prerequisites

- **CrowdSec Security Engine** (>= 1.5.6) installed and running
- **CrowdSec Security Engine** (>= 1.6.0) installed and running
- A compatible remediation component (bouncer) for your web server or reverse proxy

## AppSec Component Setup
Expand Down Expand Up @@ -59,7 +59,7 @@ sudo mkdir -p /etc/crowdsec/acquis.d/
2. Create the AppSec acquisition configuration:

```bash
sudo cat > /etc/crowdsec/acquis.d/appsec.yaml << EOF
sudo tee /etc/crowdsec/acquis.d/appsec.yaml > /dev/null << EOF
appsec_configs:
- crowdsecurity/appsec-default
labels:
Expand Down
1 change: 1 addition & 0 deletions crowdsec-docs/docs/appsec/quickstart/traefik.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ If a crowdsec container is already running, stop/remove it before re-running wit
```bash
docker run -d --name crowdsec \
-v /path/to/original:/etc/crowdsec \
-v /var/lib/crowdsec/data/:/var/lib/crowdsec/data/ \
-v ./appsec.yaml:/etc/crowdsec/acquis.d/appsec.yaml \
crowdsecurity/crowdsec
```
Expand Down
4 changes: 2 additions & 2 deletions crowdsec-docs/docs/appsec/rules_examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -584,12 +584,12 @@ Modify the default remediation for specific rules.
```yaml
pre_eval:
- apply:
- SetRemediationByName('some-rule', 'log')
- SetRemediationByName('some-rule', 'allow')
```

#### Use Case

Change a blocking rule to log-only mode for testing.
Let requests matching a blocking rule through while still generating alerts, for testing.

### 4. Disable Rules by ID

Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/appsec/rules_syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ We recommend using this format only to use existing rules you may have.
There are 2 ways to provide CrowdSec with seclang rules:

- Provide rules directly by using the `seclang_rules` parameter in your rule file
- Provide a file containing the rules by using the `seclang_rules_file` parameter in your rule file. The file must be located inside CrowdSec data directory
- Provide a file containing the rules by using the `seclang_files_rules` parameter in your rule file. The file must be located inside CrowdSec data directory

The default paths for the data directory per OS:

Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/central_api/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The [Central API](https://crowdsecurity.github.io/api_doc/capi/) is the service


:::info
This information is *only* going to be pushed when a scenario is coming from the hub and is unmodified. Custom scenarios, tainted scenarios and manual decisions are *not* pushed unless enrolled into the console.
Alerts from custom and tainted scenarios are pushed by default (opt out with `cscli console disable custom` or `cscli console disable tainted`). Manual decisions are only pushed when the `manual` console option is enabled, which `cscli console enroll` does by default.
:::

When the Security Engine generates an alert, [unless you opt-out of it](/u/troubleshooting/security_engine#how-to-disable-the-central-api), it will push "signal meta-data". The meta-data are :
Expand Down
4 changes: 2 additions & 2 deletions crowdsec-docs/docs/configuration/crowdsec_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ Log output destination. Can be `stdout`, `file`, or `syslog`.

Log level. Can be `error`, `info`, `debug`, `trace`.

#### `log_folder`
#### `log_dir`
> string

Folder to write log file.
Expand Down Expand Up @@ -974,7 +974,7 @@ server:
tls:
cert_file: <path_to_certificat_file>
key_file: <path_to_certificat_key_file>
client_verification: "NoClientCert|RequestClientCert|RequireAnyClientCert|VerifyClientCertIfGiven|RequestAndVerifyClientCert"
client_verification: "NoClientCert|RequestClientCert|RequireAnyClientCert|VerifyClientCertIfGiven|RequireAndVerifyClientCert"
ca_cert_path: "<path_to_ca_cert_file>"
agents_allowed_ou: # List of allowed Organisational Unit for the agents
- agents_ou
Expand Down
2 changes: 1 addition & 1 deletion crowdsec-docs/docs/configuration/network_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ Both components need proper configuration to run (we decide to keep this behavio

## Notes on proxy use

- It's possible to use crowdsec through proxy, it will honor the `HTTP_PROXY` environment variable. More on the configuration how to use crowdsec through a proxy [here](/u/troubleshooting/security_engine#how-to-set-up-a-proxy)
- It's possible to use crowdsec through proxy, it honors the `HTTPS_PROXY`, `HTTP_PROXY` and `NO_PROXY` environment variables. More on the configuration how to use crowdsec through a proxy [here](/u/troubleshooting/security_engine#how-to-set-up-a-proxy)
Loading
Loading