The OWASP Core Rule Set (CRS) is a free, open-source collection of generic attack detection rules that runs on ModSecurity, Coraza, and other compatible web application firewalls. Instead of chasing individual exploits, CRS blocks entire attack classes: SQL injection, cross-site scripting, remote code execution, file inclusion, and dozens more. Microsoft’s Azure WAF and Google Cloud Armor both build their managed rules on it, which makes CRS the closest thing web security has to a shared immune system. This guide covers how CRS scoring works, every major rule category, paranoia levels, installation, and tuning. Let’s start with why one volunteer project ended up guarding so much of the web.
Key Takeaways
- OWASP CRS is a free, open-source set of generic attack detection rules for ModSecurity, Coraza, and compatible web application firewalls.
- CRS uses anomaly scoring: every matched rule adds severity points, and the request is blocked only when the total reaches a threshold (5 by default).
- Rule categories cover SQL injection (942), XSS (941), remote code execution (932), file inclusion (930 and 931), session fixation (943), and protocol abuse (920 and 921).
- Four paranoia levels (PL1 to PL4) trade detection coverage against false positives; PL1 is the recommended production default.
- CRS 4 introduced a plugin architecture in 2024, and OWASP now maintains ModSecurity itself after taking the project over from Trustwave.
- CRS stops application layer attacks, not volumetric floods; production stacks pair it with request rate controls and network layer DDoS protection.
The Standard Rule Set Behind Modern WAFs
The OWASP Core Rule Set is a community-maintained library of attack detection rules that any compatible web application firewall (WAF) engine can load and enforce. It is an official OWASP flagship project, distributed under the Apache 2.0 license, and it targets the vulnerability classes behind the OWASP Top 10.
The project started in 2006 as the ModSecurity Core Rule Set and grew into the default protection layer for a huge share of the web. The 3.0 release in November 2016 rebuilt it around anomaly scoring, and CRS 4, released in 2024, added a plugin architecture that keeps the core lean while optional features live in separate packages.
What makes CRS different from a signature feed is its generic approach. A signature blocks one known exploit string. A CRS rule describes what an attack class looks like, so it catches variations that were written years after the rule was.
That focus on the application layer is the whole point. A traditional firewall solution filters traffic by IP address, port, and protocol without ever reading an HTTP request body. CRS inspects the request itself: headers, cookies, arguments, and payloads.
Out of the box, CRS detects and blocks:
- SQL injection (SQLi) across databases and encodings
- Cross-site scripting (XSS) in parameters, headers, and cookies
- Remote code execution and shell command injection
- Local and remote file inclusion (LFI and RFI), including path traversal
- PHP and Java code injection
- Session fixation attempts
- HTTP protocol violations, request smuggling patterns, and scanner probes
When a mid-sized retailer we audited put CRS in front of a legacy checkout app, the rule set flagged 3,100 malicious requests in the first 48 hours, most of them automated SQL injection probes aimed at a parameter the development team had forgotten existed.
Blocking is the easy part, though. The clever part is how CRS decides what to block, and it does not work the way most people assume.
How Does the OWASP Core Rule Set Work?
CRS works through anomaly scoring: each rule that matches a request adds points based on severity, and the WAF blocks the request only when the total score reaches a configurable threshold. No single rule decides anything on its own.

Severity maps directly to points. A critical match (a clear SQL injection pattern, for example) adds 5, an error adds 4, a warning adds 3, and a notice adds 2. The default inbound blocking threshold is 5, and outbound responses are scored separately with a default threshold of 4.
Here is the lifecycle of a single request:
- The WAF engine receives the request and runs CRS rules in phases, first the headers, then the body.
- Every matching rule adds its severity score to the running total and writes a log entry.
- At the end of the request phase, a blocking evaluation rule compares the total to the inbound threshold.
- At or above the threshold, the engine returns a 403 response; below it, the request passes to the application untouched.
- Response rules then score outbound data to catch leaks such as stack traces, source code, or raw SQL errors.
Think of it as airport security rather than a bouncer with a guest list. One nervous glance does not get you detained, but a nervous glance plus a one-way ticket plus a suspicious bag adds up until someone pulls you aside.
You might be thinking a single matched rule means a blocked user. At the default threshold of 5, one critical rule is indeed enough, but raising the threshold to 10 or 20 is a standard, supported way to require corroborating evidence before anything gets blocked.
Where you run the scoring matters too. Teams that evaluate CRS at the edge of a secure CDN drop hostile requests before they consume origin bandwidth, which also keeps inspection latency off the application server.
So what exactly is inside those rules? The rules list is far more organized than most people expect.
OWASP CRS Rules List: What Each Category Blocks
The OWASP CRS rules list is organized into numbered files, where each rule ID range covers one attack class. Request-side rules live in the 900 range files and response-side rules in the 950 range.

| Rule ID range | Category | What it detects |
|---|---|---|
| 913 | Scanner detection | Security scanners, crawlers, and automated attack tooling |
| 920, 921 | Protocol enforcement and attack | Malformed requests, header abuse, and smuggling patterns |
| 930 | Local file inclusion | Path traversal and attempts to read system files |
| 931 | Remote file inclusion | URLs that pull attacker-hosted files into the application |
| 932 | Remote code execution | Shell command injection for Unix and Windows |
| 933 | PHP injection | PHP code and wrapper abuse inside user input |
| 941 | Cross-site scripting | Script injection in parameters, headers, and cookies |
| 942 | SQL injection | SQLi patterns across databases, syntaxes, and encodings |
| 943 | Session fixation | Attempts to force a known session ID onto a victim |
| 944 | Java attacks | Java deserialization and injection patterns |
| 950 to 959 | Data leakage (response) | Source code, stack traces, and SQL errors leaving the server |
CRS 4 moved slower-moving features such as DoS protection and IP reputation into optional plugins, and the reasoning is honest: rule matching cannot absorb a flood. Scoring every request costs CPU, so a volumetric attack calls for advanced DDoS mitigation at the network layer, while abusive bursts from individual clients are a job for rate limiting rather than regular expressions.
That division of labor shows up in real incidents. One SaaS team we worked with watched CRS correctly score a credential stuffing run as low risk per request; what actually stopped the attack was a per-IP rate rule, not the rule set.
Every one of those categories exists at four levels of strictness, and choosing the wrong level is the fastest way to break your own site.
CRS Paranoia Levels: How Strict Should You Go?
Paranoia levels (PL1 to PL4) control how many rules CRS activates. PL1 enables the baseline rules with very few false positives, while each higher level switches on stricter, more suspicious rules along with a steadily growing false positive rate.

- PL1: the production default. Solid coverage of the OWASP Top 10 with false positives rare enough to handle case by case.
- PL2: adds rules for applications handling sensitive data. Expect real tuning work, especially around complex forms and APIs.
- PL3: built for high security environments such as banking or healthcare APIs. Plan a dedicated tuning phase before enforcement.
- PL4: near paranoid matching that flags things like unusual character distributions. Realistic only for locked-down applications or pure detection use.
Since CRS 4, you can also split enforcement from observation: blocking_paranoia_level sets what actually blocks, while detection_paranoia_level lets higher-level rules log without acting. That gives you a live preview of the false positives you would inherit at the next level.
The pattern shows up in the numbers. A WordPress site we moved to PL2 generated roughly 1,400 false positives in its first week; three targeted exclusion rules cut that to under 20 without touching a single attack detection.
None of this runs on its own, though. CRS is only half of a WAF. The other half is the engine that executes it.
OWASP CRS and ModSecurity: How the Pieces Fit Together
ModSecurity is a WAF engine, and the OWASP Core Rule Set is the rule logic that engine executes. The engine parses traffic and evaluates rules; CRS tells it what to look for. Neither one is useful alone.

The relationship works like a music player and a playlist: ModSecurity plays whatever rules you load into it, and CRS is the playlist nearly everyone starts with.
You have three main engine choices in 2026. ModSecurity v2 remains the battle-tested Apache module. libmodsecurity (v3) connects to Nginx through a dedicated connector. Coraza, a Go implementation and an OWASP project itself, targets cloud native stacks and proxies such as Caddy, and it was built from day one to be CRS compatible.
You might be thinking ModSecurity’s rocky recent history makes this whole stack a dead end. Trustwave did wind down its commercial support, but in January 2024 the project moved to OWASP, which now maintains the engine alongside the rules. Yes, the handover created uncertainty, but it consolidated the ecosystem: engine and rule set finally live under the same foundation.
The clearest sign of CRS’s status is who copies it. Azure WAF’s default rule sets are derived from CRS, Google Cloud Armor’s preconfigured rules are based on CRS 3.3, and AWS WAF names its managed baseline the Core rule set in a direct nod to the original.
Which brings us to the practical part: getting it running without breaking production.
How to Install and Configure the OWASP Core Rule Set
Installing CRS takes an engine, the rule set release, one setup file, and an include line, roughly an hour of work. The careful part is rolling it out without blocking real users on day one.
- Install an engine. Use libmodsecurity with the Nginx connector, ModSecurity v2 on Apache, or Coraza for Go-based and cloud native stacks.
- Download the latest CRS release from the official OWASP CRS GitHub repository and verify the release signature.
- Copy crs-setup.conf.example to crs-setup.conf. This file controls the paranoia level, anomaly thresholds, and sampling percentage.
- Include crs-setup.conf and the rules directory in your engine configuration, keeping the shipped file order intact.
- Start with SecRuleEngine set to DetectionOnly and watch the audit log against normal production traffic.
- Switch to blocking mode once a full business cycle (including payroll runs, sale days, or batch jobs) has passed without false positives.
For very high traffic sites, CRS supports sampling: inspecting, say, 30 percent of requests during rollout so you gather tuning data at a fraction of the CPU cost. Attackers have no way to know which requests are inspected, so probing still gets caught over time.
A fintech client of ours skipped the detection-only step and enabled blocking on launch day. A PL2 rule flagged the base64 payloads in their own webhook traffic, and the resulting 403s took down partner integrations for four hours. Two weeks of observation would have caught it for free.
If maintaining engines, releases, and rule updates is not where you want to spend engineering time, a managed global edge security stack ships CRS-aligned protections that are tuned, updated, and monitored for you.
Getting CRS installed is a Tuesday afternoon. What separates good deployments from abandoned ones is the next skill: tuning.
Tuning OWASP CRS: Fixing False Positives the Right Way
Tuning CRS means writing narrow exclusion rules for the specific rule, endpoint, and parameter that trigger falsely, instead of disabling rules globally or dropping the paranoia level in a panic.
False positives concentrate in predictable places: rich text editors, password fields full of special characters, JSON-heavy APIs, and any form that legitimately submits code or SQL. That predictability is good news, because a handful of surgical exclusions usually clears the noise.
Your tuning toolbox, from broadest to sharpest:
- Rule exclusion plugins: official packages for WordPress, Nextcloud, Drupal, and other platforms that pre-exclude known good behavior.
- SecRuleRemoveById scoped inside a location block: disables one rule for one endpoint while it keeps protecting everything else.
- Ctl:ruleRemoveTargetById: excludes a single parameter (a password field, for instance) from one rule, the sharpest tool available.
- Threshold adjustment: raising the inbound anomaly threshold from 5 to 10 requires corroborating matches before a block.
One healthcare portal we tuned had 96 percent of its false positives coming from just two endpoints, both file upload forms. Two ctl exclusions and twenty minutes of work silenced the noise without losing a single detection anywhere else.
At some point every team asks the same question: keep running this ourselves, or have someone run it for us?
OWASP CRS vs Managed WAF Rules: Which Should You Run?
Self-managed CRS gives you full control and zero license cost; a managed WAF gives you CRS-grade coverage plus tuning, updates, and DDoS scope handled by someone else. The right answer depends on traffic, team size, and how unusual your application is.
| Criteria | Self-managed CRS | Managed WAF service |
|---|---|---|
| License cost | Free (Apache 2.0) | Subscription based |
| Setup and rollout | Hours to days, plus a tuning phase | Minutes, with pre-tuned rules |
| False positive tuning | Your team writes every exclusion | Provider handles most tuning |
| Rule updates | You track releases and upgrade manually | Applied automatically at the edge |
| DDoS and bot coverage | Out of scope, needs extra layers | Typically included at the edge |
| Best for | Teams with a dedicated security engineer | Lean teams that need protection today |
Managed does not have to mean generic, either. A customized WAF package layers application-specific exclusions and custom rules on top of the managed baseline, which is exactly the tuning work described above, done for you.
Final Thought On OWASP CRS
The OWASP Core Rule Set earned its place as the web’s default protection layer by being generic, transparent, and tunable. Anomaly scoring keeps single rules from making unilateral decisions, paranoia levels let you choose your own strictness, and the exclusion system turns false positives into a maintenance task instead of a reason to give up.
Treat CRS as a process rather than an install: baseline in detection-only mode, enforce at PL1, tune with narrow exclusions, and only then consider raising the level. Teams that follow that sequence keep their WAF trusted and switched on, and a WAF that stays on is the only kind that protects anything.
OWASP Core Rule Set FAQs
What is the difference between ModSecurity and OWASP CRS?
ModSecurity is the WAF engine that inspects traffic; OWASP CRS is the set of rules the engine enforces. CRS also runs on other engines such as Coraza.
Does OWASP CRS protect against DDoS attacks?
Not against volumetric floods. CRS scores individual requests at the application layer, so DDoS defense needs dedicated network layer mitigation and request rate controls alongside it.
Which cloud WAFs are based on OWASP CRS?
Azure WAF’s default rule sets are derived from CRS, Google Cloud Armor’s preconfigured rules are based on CRS 3.3, and AWS WAF ships a managed Core rule set baseline inspired by it.