Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

Using ModSecurity and the OWASP Core Rule Set

Your own web application firewall with ModSecurity and the OWASP Core Rule Set is free and powerful, but it does not run itself. Here is how to choose the engine, start without outages and tune the rules.

Last updated 6 min readHardening and configuration

In short: ModSecurity is a web application firewall that runs in the web server; the OWASP Core Rule Set (CRS) supplies freely available rules against common attack types. For Apache the CRS project recommends ModSecurity v2; for Nginx the v3 connector or Coraza come into question. Start in blocking mode with very high anomaly thresholds, lower them step by step and handle false positives with targeted exceptions. A PHP update is not replaced by this.

Your own WAF as an additional layer

Since PHP2Shell, many companies have been asking whether they need a web application firewall. Anyone who serves their websites through Cloudflare has had protection rules active automatically since 21 October 2026, according to Cloudflare. Anyone who does not, or does not want to route traffic through a third party, can run a WAF directly on their own server.

The best-known combination for this is ModSecurity with the OWASP Core Rule Set. Both are open source and free. The CRS is a collection of general detection rules, for example against SQL injection, cross-site scripting or the injection of files. The project itself describes its goal as general attack detection with as few false positives as possible, as one building block among several.

That also names the limit. A WAF checks requests and responses; it does not repair a vulnerability in the PHP interpreter. Why you need both is described in WAF or update: why you need both.

Which engine suits your web server

The rule set needs an engine that executes it. According to the CRS documentation there are three compatible options:

Engine Web server Classification per CRS project
ModSecurity v2 Apache (module) reference implementation, recommended for Apache
ModSecurity v3 (libModSecurity) mainly Nginx via connector only the Nginx connector is really usable in production; fails 2 to 4 percent of the CRS tests
Coraza Go-based proxies and integrations passes the CRS v4 test suite completely

Some background: ModSecurity was developed for a long time by Trustwave. In 2021 Trustwave announced it would end development in 2024. On 25 January 2024 the project passed to the OWASP Foundation. For new installations, check which version your distribution ships and how current it is.

How the Core Rule Set works

By default, the CRS does not block at the first suspicious sign. It works with anomaly points: each triggered rule adds points according to its severity, and only when the sum exceeds a threshold is the request rejected.

  1. Severities: critical 5 points, error 4, warning 3, notice 2.
  2. Threshold for requests: tx.inbound_anomaly_score_threshold, default 5.
  3. Threshold for responses: tx.outbound_anomaly_score_threshold, default 4.
  4. Paranoia levels 1 to 4 in crs-setup.conf: level 1 is the baseline protection for every server on the internet, level 2 according to the project suits applications with real user data such as online shops, levels 3 and 4 bring noticeably more false positives.

A higher paranoia level detects more but also produces more false positives. For most company websites, level 1 is the start and level 2 a later goal.

Introducing ModSecurity with OWASP CRS without paralyzing the website

For new installations, the CRS project recommends switching on blocking mode from the start, but with very high thresholds, up to 10000, and then lowering them step by step. That way you gain experience with real traffic without locking out users. You set the thresholds in crs-setup.conf:

# crs-setup.conf: start phase with very high thresholds
SecAction \
    "id:900110,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    setvar:tx.inbound_anomaly_score_threshold=10000,\
    setvar:tx.outbound_anomaly_score_threshold=10000"

Including it under Apache follows the order that the CRS documentation prescribes for plugins. Paths differ by distribution:

<IfModule security2_module>
    SecRuleEngine On
    Include /etc/modsecurity/crs/crs-setup.conf
    Include /etc/modsecurity/crs/plugins/*-config.conf
    Include /etc/modsecurity/crs/plugins/*-before.conf
    Include /etc/modsecurity/crs/rules/*.conf
    Include /etc/modsecurity/crs/plugins/*-after.conf
</IfModule>

Then evaluate the audit log defined in SecAuditLog. How to search logs systematically is described in Analyzing web server logs after an attack. Lower the thresholds in stages, for example over several weeks, until you arrive at the default value.

Handling false positives in a targeted way

False positives are normal, especially in CMS backends with editors that store HTML. The worst reaction is to switch the WAF off. Two tools are better.

First, plugins: the CRS project maintains plugins with exception rules for common applications, such as WordPress. They are copied into the plugin folder and loaded via the include lines shown above. The project keeps the official list in its plugin directory.

Second, your own narrowly scoped exceptions. Instead of switching a rule off everywhere, remove it only for the path where it interferes:

# Custom exception, load BEFORE the CRS rules (e.g. in a *-before.conf)
SecRule REQUEST_URI "@beginsWith /admin/editor/speichern" \
    "id:1000010,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveById=941100"

Take the rule ID from the false positive's audit log. Document every exception with reason and date so that it can be reviewed later.

Tip

After every change to thresholds or exceptions, test your application's critical paths: login, order, payment, contact form and editorial work. A WAF that blocks orders is quickly switched off again.

For Apache servers it is worth tackling the WAF together with the rest of the configuration; the basics are under Configuring Apache for PHP securely. How Cloudflare rules compare is shown in Cloudflare protection rules against PHP2Shell. The interim measures on the server itself are under Immediate measures if you cannot patch yet.

Conclusion: a WAF needs care

ModSecurity with the OWASP Core Rule Set gives you a powerful web application firewall without license costs and without dependence on an external service. The price is work: choose the engine to fit the web server, begin with high thresholds, evaluate false positives, maintain exceptions and keep the rules up to date.

Anyone who cannot make that effort is often better off with a well-configured cloud WAF. Anyone who does gets a layer that catches many standard attacks and provides valuable hints in the audit logs. In no case does it replace the update: against PHP2Shell, only PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 or a confirmed backport protects, followed by a restart of all PHP processes.

How does PHP SOS help?

  • Choose the engine: We review web server, distribution and available packages and recommend the suitable combination.
  • Introduce: We install the CRS with high starting thresholds, include suitable plugins and set up logging.
  • Tune: Over several weeks we evaluate false positives, create targeted exceptions and lower the thresholds.
  • Put in context: As part of WAF and virtual patching, we connect the WAF with interim measures and the path to the regular patch.

Frequently asked questions

Does the OWASP CRS protect against PHP2Shell?

You should not assume so. The Core Rule Set detects general attack patterns and is not tailored to a specific vulnerability. Cloudflare also points out that rules based on the request data alone are not enough for PHP2Shell. The PHP update remains mandatory.

Which engine should I use for Nginx?

According to the CRS project, with ModSecurity v3 only the Nginx connector is really usable in production, and v3 fails a small part of the CRS tests. Alternatively there is Coraza, which according to the project passes the CRS v4 test suite completely. For Apache the project recommends ModSecurity v2.

Is ModSecurity still maintained?

According to the CRS documentation, Trustwave had announced it would end development in 2024. On 25 January 2024 the project was handed over to the OWASP Foundation and has been continued there since.

How do I prevent the WAF from paralyzing my shop?

Start with very high anomaly thresholds, as the CRS project recommends, and lower them step by step. Evaluate the logs as you go and create targeted exceptions for your application instead of switching rules off across the board.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help