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
6 changes: 3 additions & 3 deletions content/2-how-crs-works/2-1-anomaly_scoring/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ SecRule REQUEST_HEADERS:Content-Length "!@rx ^\d+$" \
tag:'paranoia-level/1',\
tag:'OWASP_CRS',\
tag:'capec/1000/210/272',\
ver:'OWASP_CRS/3.4.0-dev',\
ver:'OWASP_CRS/4.28.0',\
severity:'CRITICAL',\
setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
```

{{% notice info %}}
Notice that the anomaly score variable name has the suffix `pl1`. Internally, CRS keeps track of anomaly scores on a *per* [*paranoia level*]({{< ref "2-2-paranoia_levels" >}} "Page describing paranoia levels.") basis. The individual paranoia level anomaly scores are added together before each round of blocking evaluation takes place, allowing the total combined inbound or outbound score to be compared to the relevant anomaly score threshold.

Tracking the anomaly score per paranoia level allows for clever scoring mechanisms to be employed, such as the [executing paranoia level]({{< ref "2-2-paranoia_levels#moving-to-a-higher-paranoia-level" >}} "Section describing the executing paranoia level feature.") feature.
Tracking the anomaly score per paranoia level allows for clever scoring mechanisms to be employed, such as the [detection paranoia level]({{< ref "2-2-paranoia_levels#moving-to-a-higher-paranoia-level" >}} "Section describing the detection paranoia level feature.") feature.
{{% /notice %}}

The rules files `REQUEST-949-BLOCKING-EVALUATION.conf` and `RESPONSE-959-BLOCKING-EVALUATION.conf` are responsible for executing the inbound (request) and outbound (response) rounds of blocking evaluation, respectively. The rules in these files calculate the total inbound or outbound transactional anomaly score and then make a blocking decision, by comparing the result to the defined threshold and taking blocking action if required.
Expand Down
14 changes: 7 additions & 7 deletions content/2-how-crs-works/2-2-paranoia_levels.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ If working in an enterprise environment, consider developing an internal policy

## Setting the Paranoia Level

If using a native CRS installation on a web application firewall, the paranoia level is defined by setting the variable `tx.paranoia_level` in the file `crs-setup.conf`. This is done in rule 900000, but technically the variable can be set in the Apache or Nginx configuration instead.
If using a native CRS installation on a web application firewall, the paranoia level is defined by setting the variable `tx.blocking_paranoia_level` in the file `crs-setup.conf`. This is done in rule 900000, but technically the variable can be set in the Apache or Nginx configuration instead.

If running CRS where it has been integrated into a commercial product or CDN then support varies. Some vendors expose the PL setting in the GUI while other vendors require a custom rule to be written that sets `tx.paranoia_level`. Unfortunately, there are also vendors that don't allow the PL to be set at all. (The CRS project considers this to be an incomplete CRS integration, since paranoia levels are a defining feature of CRS.)
If running CRS where it has been integrated into a commercial product or CDN then support varies. Some vendors expose the PL setting in the GUI while other vendors require a custom rule to be written that sets `tx.blocking_paranoia_level`. Unfortunately, there are also vendors that don't allow the PL to be set at all. (The CRS project considers this to be an incomplete CRS integration, since paranoia levels are a defining feature of CRS.)

## How Paranoia Levels Relate to Anomaly Scoring

Expand All @@ -69,19 +69,19 @@ This is *technically* correct but it overlooks the fact that there are attack ca

## Moving to a Higher Paranoia Level

### Introducing the *Executing Paranoia Level*
### Introducing the *Detection Paranoia Level*

Consider an example successful CRS installation: it operates at paranoia level 1, a handful of rule exclusions are in place to deal with false positives, and the inbound anomaly score threshold is set to 5 which blocks would-be attackers immediately. Things are running smoothly at paranoia level 1, but imagine that there's now a requirement to increase the level of security by raising the paranoia level to 2. Moving to PL 2 will *almost certainly* cause new false positives: given the strict anomaly score threshold of 5, these will likely cause legitimate users to be blocked.

There's a simple, but **risky**, way to raise the paranoia level of a working and tuned CRS installation: raise the anomaly score threshold for a period of time, in order to account for the additional false positives that are anticipated. Raising the anomaly score threshold will allow through attacks that would have been blocked previously. The idea of *decreasing* security in order to *improve* it is counter-intuitive, as well as being bad practice.

There is a better solution. First, think of the paranoia level as being the "blocking paranoia level". The rules enabled in the blocking paranoia level count towards the anomaly score threshold, which is used to determine whether or not to block a given request. Now introduce an *additional* paranoia level: the "executing paranoia level". By default, the executing paranoia level is automatically set to be equal to the blocking paranoia level. If, however, the executing paranoia level is set to be *higher* than the blocking paranoia level then the additional rules from the higher paranoia level are *executed* but will never count towards the anomaly score threshold used to make the blocking decision.
There is a better solution. First, think of the paranoia level as being the "blocking paranoia level". The rules enabled in the blocking paranoia level count towards the anomaly score threshold, which is used to determine whether or not to block a given request. Now introduce an *additional* paranoia level: the "detection paranoia level", set with the variable `tx.detection_paranoia_level` in rule 900001 of `crs-setup.conf`. By default, the detection paranoia level is automatically set to be equal to the blocking paranoia level. If, however, the detection paranoia level is set to be *higher* than the blocking paranoia level then the additional rules from the higher paranoia level are *executed* but will never count towards the anomaly score threshold used to make the blocking decision.

*Example: Blocking paranoia level of 1 and executing paranoia level of 2*
*Example: Blocking paranoia level of 1 and detection paranoia level of 2*

![Diagram showing a scenario where the blocking paranoia level and the executing paranoia level are different. The active and inactive paranoia levels are emphasized to explain the concept.](https://coreruleset.org/images/2021/10/executing-paranoia-level-1.png?width=25em)
![Diagram showing a scenario where the blocking paranoia level and the detection paranoia level are different. The active and inactive paranoia levels are emphasized to explain the concept.](https://coreruleset.org/images/2021/10/executing-paranoia-level-1.png?width=25em)

**The executing paranoia level allows rules from a higher paranoia level to be run, and potentially to trigger false positives, without increasing the probability of blocking legitimate users.** Any new false positives can then be tuned away using rule exclusions. Once ready and with all the new rule exclusions in place, the blocking paranoia level can then be raised to match the executing paranoia level. This approach is a flexible and secure way to raise the paranoia level on a working production system *without* the risk of new false positives blocking users in error.
**The detection paranoia level allows rules from a higher paranoia level to be run, and potentially to trigger false positives, without increasing the probability of blocking legitimate users.** Any new false positives can then be tuned away using rule exclusions. Once ready and with all the new rule exclusions in place, the blocking paranoia level can then be raised to match the detection paranoia level. This approach is a flexible and secure way to raise the paranoia level on a working production system *without* the risk of new false positives blocking users in error.

## Moving to a Lower Paranoia Level

Expand Down
20 changes: 3 additions & 17 deletions content/2-how-crs-works/2-3-false-positives-and-tuning.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,30 +373,16 @@ Multiple conditions can also be chained together to create a logical AND by usin

#### Rule Exclusion Packages

CRS ships with prebuilt *rule exclusion packages* for a selection of popular web applications. These packages contain application-specific rule exclusions designed to prevent false positives from occurring when CRS is put in front of one of these web applications.
*Rule exclusion packages* provide application-specific rule exclusions for a selection of popular web applications, designed to prevent false positives from occurring when CRS is put in front of one of these web applications.

The packages should be viewed as a good *starting point* from which to build upon. Some false positives may still occur, for example if working at a high paranoia level, if using a very new or old version of the application, if using plug-ins, add-ons, or user customizations.

If using a native CRS installation, rule exclusion packages can be enabled in the file `crs-setup.conf`. Modify rule 900130 to select the web applications in question, e.g. to enable the DokuWiki rule exclusion package use `setvar:tx.crs_exclusions_dokuwiki=1`, and then uncomment the rule to enable it.
As of CRS 4, rule exclusion packages are no longer part of the rule set itself: each one is distributed as a separate plugin. To use one, install the plugin for the web application in question as described on the [plugins]({{% ref "4-about-plugins/" %}}) page. Once installed, a plugin is enabled by default.

If running CRS where it has been integrated into a commercial product or CDN then support varies. Some vendors expose rule exclusion packages in the GUI while other vendors require custom rules to be written which set the necessary variables. Unfortunately, there are also vendors that don't allow rule exclusion packages to be used at all.

{{% notice style="tip" icon="location-dot" %}}
If running multiple web applications, it is highly recommended to enable a rule exclusion package only for the location where the corresponding web application resides. For example, to enable the WordPress rule exclusion package only for locations under '/wordpress', a rule like the following could be used:

```apache
SecRule REQUEST_URI "@beginsWith /wordpress/" setvar:tx.crs_exclusions_wordpress=1...
```
Or if CRS is running on an reverse-proxy with multiple apps, you can enable plugins per domain using either [SecWebAppID](https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v2.x)#user-content-SecWebAppId) (Unsupported on Coraza):
```apache
SecRule WebAppID "@streq wordpress" setvar:tx.crs_exclusions_wordpress=1...
```

or the Host header:
```apache
SecRule REQUEST_HEADERS:Host "@streq wordpress.example.com" setvar:tx.crs_exclusions_wordpress=1...

```
If running multiple web applications, it is highly recommended to enable a rule exclusion package only for the application it belongs to. Plugins can be limited to a single location, `WebAppID`, or hostname, as described under [conditionally enable plugins for multi-application environments]({{% ref "4-about-plugins/4-1-plugins#conditionally-enable-plugins-for-multi-application-environments" %}}).
{{% /notice %}}

Rule exclusion packages are currently available for the following web applications:
Expand Down
26 changes: 13 additions & 13 deletions content/6-development/6-4-using-the-crs-sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ curl -H "x-format-output: txt-matched-rules" https://sandbox.coreruleset.org/?fi

930120 PL1 OS File Access Attempt
932160 PL1 Remote Command Execution: Unix Shell Code Found
949110 PL1 Inbound Anomaly Score Exceeded (Total Score: 10)
980130 PL1 Inbound Anomaly Score Exceeded (Total Inbound Score: 10 - SQLI=0,XSS=0,RFI=0,LFI=5,RCE=5,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 10, 0, 0, 0
949110 PL? Inbound Anomaly Score Exceeded (Total Score: 10)
980170 PL? Anomaly Scores: (Inbound Scores: blocking=10, detection=10, per_pl=10-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=5, RCE=5, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=10)
```

In this example, we sent `?file=/etc/passwd` as a GET payload. The CRS should catch the string `/etc/passwd` which is on our blocklist. Try out the command in a terminal now if you like!
Expand All @@ -165,18 +165,18 @@ The sandbox also adds a `X-Unique-Id` header to the response. It contains a uniq

```bash
curl -i -H 'x-format-output: txt-matched-rules' \
'https://sandbox.coreruleset.org/?test=posix_uname()'
HTTP/1.1 200 OK
Date: Tue, 25 Jan 2022 13:53:07 GMT
Content-Type: text/plain
'https://sandbox.coreruleset.org/?test=system()'
HTTP/1.1 403 Forbidden
Date: Sun, 30 Aug 2026 15:55:39 GMT
Content-Type: text/plain; charset=iso-8859-1
Transfer-Encoding: chunked
Connection: keep-alive
X-Unique-ID: YfAAw3Gq8uf24wZCMjHTcAAAANE
x-backend: apache-latest
X-Unique-ID: apRSe3-zbbw7NqPHTKoqQwAAAI8
x-backend: apache-v4-lts

933150 PL1 PHP Injection Attack: High-Risk PHP Function Name Found
949110 PL1 Inbound Anomaly Score Exceeded (Total Score: 5)
980130 PL1 Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=5,HTTP=0,SESS=0): individual paranoia level scores: 5, 0, 0, 0
933160 PL1 PHP Injection Attack: High-Risk PHP Function Call Found
949110 PL? Inbound Anomaly Score Exceeded (Total Score: 5)
980170 PL? Anomaly Scores: (Inbound Scores: blocking=5, detection=5, per_pl=5-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0, PHPI=5, HTTP=0, SESS=0, COMBINED_SCORE=5)
```

## Default options
Expand Down Expand Up @@ -270,8 +270,8 @@ The payload is being detected by triggering the following rules:

930120 PL1 OS File Access Attempt
932160 PL1 Remote Command Execution: Unix Shell Code Found
949110 PL1 Inbound Anomaly Score Exceeded (Total Score: 10)
980130 PL1 Inbound Anomaly Score Exceeded (Total Inbound Score: 10 - SQLI=0,XSS=0,RFI=0,LFI=5,RCE=5,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 10, 0, 0, 0
949110 PL? Inbound Anomaly Score Exceeded (Total Score: 10)
980170 PL? Anomaly Scores: (Inbound Scores: blocking=10, detection=10, per_pl=10-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=5, RCE=5, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=10)

CRS therefore detects this payload starting with paranoia level 1.
```
Expand Down
Loading