Why ModSecurity Goes on Every Client Server by Default
Advertisement
ModSecurity, strongly paired with the OWASP Core Rule Set (CRS), goes onto every single 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 literally isn't there yet? But that is exactly the point. CRS is not tuned to a specific application. It is strictly tuned to the exact kinds of requests that automated attacks aggressively send to every server, simply assuming that something, somewhere, might be vulnerable to them.
What it is actually catching
Run almost any web server with logging turned all the way up, and you will see a constant, massive stream of requests that have absolutely nothing to do with the actual application.
You will see aggressive attempts to access /wp-admin on a server that is not even running WordPress. You will see SQL injection payloads shoved into query parameters of pages that do not even take query parameters. You will see path traversal attempts (../../etc/passwd) violently thrown against static file paths. You will see requests completely loaded with payloads explicitly designed to exploit vulnerabilities in software that was never even installed.
Absolutely none of these need to succeed to be a problem. They are heavy noise at best. At worst, they are a very real risk if even one single piece of installed software happens to match what they are aggressively probing for.
CRS strictly recognizes the patterns behind these, not specific application vulnerabilities. A SQL injection attempt structurally looks exactly like a SQL injection attempt, whether it is aimed at a completely custom PHP app, a random WordPress plugin, or a static site with no database at all (where it will fail anyway, but absolutely still represents a malicious probe worth knowing about). That structural recognition is exactly what makes it so incredibly useful without requiring any application-specific configuration upfront.
Detection mode first, always
The most common reason people give up and turn ModSecurity off entirely is a false positive that violently blocks legitimate traffic. This is usually discovered when a furious customer cannot submit a basic form because their perfectly normal input just happened to match a rule pattern.
The fix for this is not disabling ModSecurity. The fix is deploying it strictly in detection mode first:
# modsecurity.conf
SecRuleEngine DetectionOnly
In this mode, ModSecurity quietly logs what it would have blocked without actually blocking a single thing. Running for a week or two in this mode against real, live traffic cleanly surfaces any false positives for the specific application. These can then be specifically addressed with highly targeted exclusion rules, long before switching to blocking mode:
SecRuleEngine On
This careful two-step rollout is the literal difference between "ModSecurity blocked a customer and got disabled entirely, leaving the server completely naked with no WAF at all" and "ModSecurity has a couple of highly tuned exceptions and is actively blocking everything else."
Tuning exclusions is perfectly normal, not a failure
CRS deliberately ships with a "paranoia level" setting. Higher levels aggressively catch more but produce significantly more false positives. The default level is a perfectly reasonable starting point.
Any exclusions needed beyond that are typically scoped extremely narrowly, to a specific rule ID and for a specific URL path, rather than blindly disabling broad, entire categories of protection:
SecRuleRemoveByIdWithMsg "rule message text" "specific-form-endpoint"
A small handful of exclusions for an application's specific quirks (a rich text editor that legitimately submits HTML-like content, for example) is completely normal. It absolutely does not undermine the protection for everything else on the entire server. The real goal is not zero exclusions; the goal is a WAF that is actually turned on and actively blocking, with just the small number of exact exceptions that an application genuinely needs.
The performance cost is much smaller than the alternative
ModSecurity absolutely does add overhead. Every single request gets actively evaluated against the rule set before ever reaching the application.
In real-world practice, this overhead is incredibly small compared to the application's own processing time for most requests. Furthermore, it is overhead that strictly scales with the size of the rule set, not with the complexity of your application. Weighed against the brutal alternative—a completely naked server with absolutely zero generic protection against the constant, grinding baseline of automated probing—the tradeoff is heavily, heavily in favor of having it turned on.
Why "by default" matters so much
The exact reason this goes on every single server before the application is even decided is that the generic protection it offers absolutely does not depend on knowing the application.
By the time an application is finally deployed and a formal security review might happen, a server with no WAF has already been actively exposed to whatever has been violently probing it since the second it got a public IP address.
Starting with ModSecurity in detection mode from day one, and then securely moving to blocking once the application's specific traffic patterns are fully understood, means the vulnerable gap between "server exists" and "server has a strong baseline protection" is effectively zero. It does not wait for however long it takes for someone to finally remember to add it.
Advertisement