[ OK ]Initializing kernel...
~/im/blog
Hire Me

Let's Talk

Interested in working together or have a question? I'm always open to discussing new projects.

Get in touch

Connect

Find me on social media and professional networks.

Privacy PolicyTerms of Conditions
© 2026 Irfan MiralDeveloped byirfanMiral.com
HomeAbout/ResumeBlogContact
2026-11-25• 6 min read

Why ModSecurity Goes on Every Client Server by Default

Security ModSecurity Web Application Firewall Security

ModSecurity, paired with the OWASP Core Rule Set (CRS), goes onto every server I set up, before I know much of anything about what application will eventually run on it. That might sound backwards, how do you configure a web application firewall for an application that isn't there yet, but it's exactly the point. CRS isn't tuned to a specific application, it's tuned to the kinds of requests that automated attacks send to every server, on the assumption that something, somewhere, might be vulnerable to them.

What it's actually catching

Run almost any web server with logging turned up and you'll see a constant stream of requests that have nothing to do with the actual application: attempts to access /wp-admin on a server that isn't running WordPress, SQL injection payloads in query parameters of pages that don't take query parameters, path traversal attempts (../../etc/passwd) against static file paths, requests with payloads designed to exploit vulnerabilities in software that was never installed. None of these need to succeed to be a problem, they're noise at best and a real risk at worst if even one piece of installed software happens to match what they're probing for.

CRS recognizes the patterns behind these, not specific application vulnerabilities. A SQL injection attempt looks structurally like a SQL injection attempt whether it's aimed at a custom PHP app, a WordPress plugin, or a static site with no database at all (where it'll fail anyway, but still represents a probe worth knowing about). That structural recognition is what makes it useful without application-specific configuration.

Detection mode first, always

The most common reason people turn ModSecurity off entirely is a false positive blocking legitimate traffic, usually discovered when a customer can't submit a form because their input happened to match a rule pattern. The fix for this isn't disabling ModSecurity, it's deploying it in detection mode first:

# modsecurity.conf
SecRuleEngine DetectionOnly

In this mode, ModSecurity logs what it would have blocked without actually blocking anything. Running for a week or two in this mode against real traffic surfaces any false positives for the specific application, which can then be addressed with targeted exclusion rules, before switching to blocking mode:

SecRuleEngine On

This two-step rollout is the difference between "ModSecurity blocked a customer and got disabled entirely, leaving the server with no WAF at all" and "ModSecurity has a couple of tuned exceptions and is actively blocking everything else."

Tuning exclusions is normal, not a failure

CRS ships with a "paranoia level" setting, higher levels catch more but produce more false positives. The default level is a reasonable starting point, and any exclusions needed beyond that are typically scoped narrowly, to a specific rule ID, for a specific URL path, rather than disabling broad categories of protection:

SecRuleRemoveByIdWithMsg "rule message text" "specific-form-endpoint"

A handful of exclusions for an application's specific quirks (a rich text editor that legitimately submits HTML-like content, for example) is completely normal and doesn't undermine the protection for everything else on the server. The goal isn't zero exclusions, it's a WAF that's actually turned on and blocking, with the small number of exceptions an application genuinely needs.

The performance cost is smaller than the alternative

ModSecurity does add overhead, every request gets evaluated against the rule set before reaching the application. In practice, this overhead is small compared to the application's own processing time for most requests, and it's overhead that scales with the size of the rule set, not with application complexity. Weighed against the alternative, a server with no generic protection against the constant baseline of automated probing, the tradeoff is heavily in favor of having it on.

Why "by default" matters

The reason this goes on every server before the application is even decided is that the protection it offers doesn't depend on knowing the application. By the time an application is deployed and a security review might happen, a server with no WAF has already been exposed to whatever's been probing it since it got an IP address. Starting with ModSecurity in detection mode from day one, then moving to blocking once the application's specific traffic patterns are understood, means the gap between "server exists" and "server has baseline protection" is effectively zero, rather than however long it takes for someone to think to add it.

PreviousIs SSH 2FA Worth the Hassle?Next Self-Hosting Nextcloud: What I Set Up Differently From the Defaults