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

        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"

        ErrorDocument 509 "Special Rate Limit Exceeded!"


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?


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”

And similarly for your other rules.

  • You're right, switching to phase 2 makes it work. – André Fernandes Oct 3 '17 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.