0

I'm trying to set up request throttling for certain sensitive URIs in an apache (v2.2) virtualhost with mod_security, but finding trouble with the use of LocationMatch. So far the configuration is as follows:

<VirtualHost *:80>
        ServerName www.example.com

        RewriteEngine On

        DocumentRoot "/var/www/html/www.example.com"

        <Directory "/var/www/html/www.example.com">
            Options None
            AllowOverride None
            Order allow,deny
            Allow from all
        </Directory>

        SecRuleEngine On
        # ignore requests from localhost or some other IP
        SecRule REMOTE_ADDR "^127\.0\.0\.2$" "phase:1,id:'1',nolog,allow"

        <LocationMatch "^\/RESTv2\/auth\..+">
                SecRule REQUEST_FILENAME ".*" "phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.requests.auth=+1,id:'3',expirevar:ip.requests.auth=1"
                SecRule ip:requests.auth "@gt 2" "phase:1,pass,log,logdata:'blocking auth %{REMOTE_ADDR} req/sec: %{ip.requests}',setvar:ip.block.auth=1,expirevar:ip.block.auth=5,id:'4'"
                SecRule ip:block.auth "@eq 1" "phase:1,deny,id:'999',nolog,logdata:'blocking RESTv2/auth.json for %{REMOTE_ADDR} req/sec: %{ip.requests.auth}', status:509"
        </LocationMatch>

        ErrorDocument 509 "Special Rate Limit Exceeded!"

</VirtualHost>

The trouble is that the LocationMatch directive is never matching, even if I reduce it to someting as general as .*. I've also tried with and without escapes for / characters in the regex, without any difference in behaviour.

If I comment out the open and close tags, the throttling rules work as expected, it's just that they never kick in when inside the LocationMatch tags. The /RESTv2/auth.json file exists inside the DocumentRoot directory, and is served normally.

I'm invoking the throttled requests as curl http://www.example.com/RESTv2/auth.json.

Is this an issue with the use of LocationMatch, or is there some weird interaction between it and the mod_security rules?

André Fernandes
  • 959
  • 7
  • 24

1 Answers1

1

ModSecurity phase 1 rules are processed before LocationMatch directives.

Therefore you need to either change these to phase 2 rules (which may not be desirable as will waste time processing all phase 1 rules instead of blocking these immediately) or use ModSecurity syntax and chained rules to replace the LocationMatch syntax:

SecRule REQUEST_URI "^\/RESTv2\/auth\..+" phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.requests.auth=+1,id:'3',expirevar:ip.requests.auth=1,chain”
    SecRule REQUEST_FILENAME ".*"

And similarly for your other rules.

Barry Pollard
  • 4,461
  • 14
  • 26