'Remove target from CRS rule based on multiple criteria

I have a WordPress site. The WP site is running behind a reverse proxy (Apache 2.4.37) with ModSecurity 2.9.7, and the OWASP Core Ruleset 3.1.0.

The WP site has a home-built theme, that requires periodical edits (updating the token in a shortcode) to keep working (... yes, I know! But it wasn't me that did that ...). Naturally enough, that editing trips up ModSecurity.

I do have the rule exclusions that allows that editing -- but I want to restrict it to an IP-range, and also to the relevant REQUEST_URI and REQUEST_HEADERS:Referer.

First try:

SecRule REQUEST_URI "@beginsWith /wp-admin/admin-ajax.php" "phase:1,chain,nolog,pass,id:20010,ctl:ruleRemoveTargetById=933100;ARGS:newcontent"
 SecRule REQUEST_HEADERS:Referer "@rx (?i)^https://example\.com/wp-admin/theme-editor\.php.*" "chain"
 SecRule REMOTE_ADDR "@ipMatch 1.2.3.0/23,1.2.5.128/25"

This indeed opens the WAF/removes the target, but does not restrict to the IP-range -- nor to Referer, probably. Investigating, I found a old comment pointing out that non-disruptive actions are executed as soon as the rule matches. ctl is a non-disruptive action ...

Second try -- move the ctl action to the last rule in the chain:

SecRule REQUEST_URI "@beginsWith /wp-admin/admin-ajax.php" "phase:1,chain,nolog,pass,id:20010"
 SecRule REQUEST_HEADERS:Referer "@rx (?i)^https://example\.com/wp-admin/theme-editor\.php.*" "chain"
 SecRule REMOTE_ADDR "@ipMatch 1.2.3.0/23,1.2.5.128/25" "ctl:ruleRemoveTargetById=933100;ARGS:newcontent"

This do not remove the target, in either case (external or internal).

Is there a way to make the chain approach work, with the ctl action? Or is there an alternative approach?



Solution 1:[1]

ModSecurity Core Rule Set Developer on Duty here. I've just tested your rule exclusion chain and it works for me. If I had to guess why it's not working for you, I'd start looking at that regular expression.

Replace the regular expression with @unconditionalMatch and see if it starts working for you. E.g.:

SecRule REQUEST_HEADERS:Referer "@unconditionalMatch" "chain"

If that doesn't work then try replacing the @ipMatch operator in the same way. You'll quickly discover which rule is causing your trouble.

Also, CRS version 3.1.0 is unsupported and considered to be insecure. At the very least, you should consider updating to the latest minor release of the 3.1.x line, which is v3.1.2.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1