ModSecurity inspects requests before they reach a site and blocks the ones matching its rules. It stops a large amount of automated attack traffic without anyone configuring anything.
It also blocks legitimate requests, and as the server administrator you are the one who decides what to do about that. The judgement involved is the whole subject.
What a false positive looks like
Almost always a 403 on a specific action instead of a whole site.
Saving a page in a page builder. Submitting a form containing code or SQL-like text. Uploading a particular file. A plugin's admin screen that sends an unusual request.
The client's report is "the site works but I cannot save my page", and that shape (one action failing, everything else fine) is the signature.
Find the rule before changing anything
WHM's ModSecurity Tools shows recent hits with the rule ID, the request, and which part of it matched.
Reproduce the problem, then look at the most recent entry. That gives you the exact rule, which is what makes a narrow fix possible.
Without the ID you are guessing, and guessing here means disabling more than you need to, which is how servers end up with the protection nominally on and effectively off.
Disable narrowly, in this order
Once you have the rule ID, there is a hierarchy of responses. Take the first one that works.
Disable the rule for one account. Everyone else keeps the protection. This is the right answer in most cases.
Disable the rule for one domain, if the tooling supports that granularity.
Disable the rule server-wide, only when it is a genuinely bad rule producing false positives across many accounts.
Disable ModSecurity for the account. The last resort, and worth recording somewhere with a date, because an exception nobody remembers becomes permanent.
What is never right is turning ModSecurity off server-wide because one client had a problem.
Check it is actually a false positive
The step people skip.
A rule firing on a request containing SQL fragments might be catching a real attempt in place of an awkward form submission. Look at the request itself and at where it came from.
A blocked request from the client's own IP while they were working is a false positive. The same rule firing from an address in another country at three in the morning is the system doing its job, and disabling the rule would be a mistake with consequences later.
Rule sets
WHM offers several vendors' rule sets, and they differ in how aggressive they are.
Running more than one is not additive protection in a useful way. It multiplies false positives, because each set has its own idea of what is suspicious, and you end up maintaining exceptions for all of them.
Pick one that matches your tolerance. A conservative set blocks less and generates almost no support load; an aggressive one blocks more and costs you time. Both are defensible; running three is not.
Update the rules
Rule sets are updated as new attack patterns appear, and an unmaintained set protects against last year's attacks.
Enable automatic updates for the vendor set you chose. Then watch for a rise in blocked legitimate requests after an update, because a new rule occasionally over-matches.
That is the trade: current rules with occasional surprises, against stale rules with none. Take the first.
What the client should be told
The default 403 tells the client nothing, and they will conclude the site is broken.
Two things help. A support process that asks for the time and the exact action, because that is what you need to find the rule. And, where you can, telling clients that a security system blocked the request instead of leaving them to guess: what ModSecurity blocks and why is written for them and is worth linking from your support replies.
What it does not replace
ModSecurity blocks requests matching known patterns. It does not patch the vulnerability those requests are aiming at.
A site running an outdated plugin with a known flaw is protected only as long as attackers use the exact shape of request the rules recognise. The fix is the update; ModSecurity buys time.
It also does nothing about weak passwords, since a correct login is not a suspicious request. Securing WordPress goes into the parts that are the site owner's job.
A working policy
One rule set, updated automatically. Exceptions granted per account, never server-wide unless the rule is genuinely faulty. Every exception recorded with a date and a reason. A quarterly look at whether the old ones are still needed.
That keeps the protection meaningful. The alternative (an accumulation of undocumented exceptions) ends with a server where nobody can say what is still protected.
Record the exception and why it exists
A rule disabled during an incident stays disabled, and within a year nobody can say whether it is still needed.
grep -rn 'SecRuleRemoveById\|SecRuleEngine' /etc/apache2/conf.d/ ~/public_html/.htaccess 2>/dev/null | head date
Write the rule number, the date, what it was blocking and what would make it removable. Three lines, kept with the account's notes rather than in a ticket.
Without that, a review either leaves every exception in place because it might matter, or removes one that was holding a genuine problem at bay. Both come from the same missing sentence.
Re-check exceptions after a rule set update
Rule numbers are not permanent, and an update can renumber or replace the rule an exception refers to.
grep -c 'SecRule' /etc/apache2/conf.d/modsec_vendor_configs/*/*.conf 2>/dev/null | tail -3 grep -i 'modsec' ~/logs/example.com.error.log | tail -5
An exception naming a rule that no longer exists does nothing, and the original false positive returns without anybody connecting it to the update.
An exception that now refers to a different rule is worse, since it disables protection nobody intended to remove. Reading the list after each update is the check that catches both.