Firewalls & Network Security

ModSecurity and OWASP CRS basics: anomaly scoring, paranoia levels and tuning a web application firewall

How OWASP CRS scores requests, how to pick a paranoia level and tune false positives, and where ModSecurity and CRS versions stand on Debian in 2026.

Published
Reading time
6 min read

A web application firewall (WAF) inspects HTTP requests and responses and blocks those that look like attacks such as SQL injection, cross-site scripting or path traversal. On self-managed Linux servers the most common open-source combination is the ModSecurity engine with the OWASP Core Rule Set (CRS). It is a useful extra layer, but only if it is tuned: an untuned WAF either blocks real customers or gets switched off.

This guide explains how CRS decides what to block, how to roll it out safely, and which versions are current as of October 2026.

The pieces and their versions

  • ModSecurity is the engine, now maintained under OWASP on GitHub. Version 2 is an Apache module; version 3 (libmodsecurity) is a standalone library used with connectors such as ModSecurity-nginx. Both lines received releases on 29 September 2026 (2.9.15 and 3.0.17).
  • CRS is the rule set. The CRS project lists 4.30.0 as the latest release and 4.25.2 as the long-term support (LTS) release, both from 2 October 2026, and states that CRS 3.3.x has reached end of life and that organisations still running it should migrate. CRS also runs on the Coraza engine.

Distribution packages lag behind. Debian 12 and Debian 13 package ModSecurity 2.9.x for Apache (libapache2-mod-security2), libmodsecurity 3.0.x with an Nginx module, and CRS from the 3.3 line (modsecurity-crs). That is fine for learning and for a first deployment, but plan to move to CRS 4: the CRS project's migration series says CRS 3.3 receives no false-positive fixes or new detections. If you combine an upstream CRS release with distribution engines, read its release notes first: the July 2026 release notes ask for ModSecurity 2.9.14 or libmodsecurity 3.0.16, newer than the 2.9.11 and 3.0.14 that Debian 13 ships.

How CRS decides: anomaly scoring

CRS does not block on the first matching rule. According to its anomaly scoring documentation, each matching rule adds to a score, and once all request rules have run the request is blocked if its score reaches the inbound threshold; responses are scored and checked against an outbound threshold in the same way.

  • Most detected attacks carry a score of 5 (critical).
  • The default thresholds are 5 for requests and 4 for responses, so one critical match blocks a request.
  • The CRS team warns that raising thresholds above the defaults lets a substantial number of attacks through.

Paranoia levels

The paranoia level (PL) decides how many rules are active:

LevelIntended for
PL 1 (default)Baseline protection for any site, with rare false positives
PL 2Sites handling real user data, such as an online shop; expect false positives to tune
PL 3Online-banking level; many false positives
PL 4Very sensitive services; a large number of false positives and weeks of tuning

The docs suggest mapping risk to level: no personal data, PL 1; personal data such as names and addresses, PL 2; sensitive financial data, PL 3. Start at PL 1 regardless and move up once it runs cleanly.

A cautious rollout on Debian with Apache

sudo apt update
sudo apt install libapache2-mod-security2 modsecurity-crs
sudo a2enmod security2
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
sudo apachectl configtest && sudo systemctl restart apache2

Debian's module configuration includes every *.conf in /etc/modsecurity and loads CRS from /usr/share/modsecurity-crs; the CRS settings file is /etc/modsecurity/crs/crs-setup.conf. The recommended engine configuration starts with SecRuleEngine DetectionOnly: rules run and are logged, but nothing is blocked.

Run in DetectionOnly long enough to see normal traffic, including logins, checkouts, file uploads, admin pages and API clients. Review what would have been blocked; the audit log location is set by SecAuditLog in modsecurity.conf. Then switch to SecRuleEngine On. The CRS docs also describe an alternative: start in blocking mode with very high thresholds (even 10000) and lower them step by step to the defaults.

The paranoia level and thresholds live in crs-setup.conf, in rules 900000 and 900110. In CRS 4 the paranoia variable is tx.blocking_paranoia_level; CRS 3.3 used tx.paranoia_level.

Tuning false positives

A false positive is a legitimate request that scores high, for example a CMS editor saving HTML, or a password field containing characters that look like SQL. Fix it with a rule exclusion as narrow as possible, as the tuning guide describes:

  • SecRuleRemoveById disables a rule everywhere (coarse; use sparingly).
  • SecRuleUpdateTargetById stops a rule inspecting one parameter or cookie everywhere.
  • ctl:ruleRemoveById and ctl:ruleRemoveTargetById inside your own rule do the same only for a given path or condition (preferred).

For example, to stop rule 941320 inspecting a parameter named wp_post:

SecRuleUpdateTargetById 941320 "!ARGS:wp_post"

Exclusions belong in the files CRS provides for them (REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf and RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf, created from their .example versions), not in edits to the rule files, which updates overwrite. CRS 4 replaced the old application exclusion packages with plugins; if you used an exclusion package under CRS 3, install the matching plugin.

Pitfalls

  • Raising the anomaly threshold to silence false positives instead of writing exclusions.
  • Jumping straight to PL 3 or 4 in blocking mode.
  • Leaving DetectionOnly on for months and never reading the logs.
  • Treating the WAF as a substitute for patching the application. It reduces risk; it does not fix vulnerable code.

What you should do

  • Start with PL 1 and default thresholds, in DetectionOnly or with very high thresholds.
  • Review logs against real traffic and write narrow exclusions in the exclusion files.
  • Switch to blocking, then consider PL 2 if you handle personal data.
  • Plan the move from CRS 3.3 to a CRS 4 release, checking engine version requirements in the release notes.
  • Keep the application, the engine and the rule set updated.

Sources

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship Firewalls & Network Security for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.