4

I'm using OWASP core rule set 3.2.0 set up with ModSecurity 3.0.4 and ModSecurity-nginx.

If I have a rule exclusion like this, in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:

 SecRule REQUEST_URI "@beginsWith /api.php" \
     "id:1015,\
     phase:2,\
     pass,\
     nolog,\
     ctl:ruleRemoveById=941160"

How do I also limit this exclusion to a specific hostname? For example, wiki.example.com.

Esa Jokinen
  • 43,252
  • 2
  • 75
  • 122
nnyby
  • 298
  • 3
  • 5
  • 16

2 Answers2

6

Using REQUEST_HEADERS:Host chained with REQUEST_URI does the trick, but gets harder to maintain, if there are several sites that either need or don't need the exclusion. Therefore, an alternative solution would be disabling the rules on the Nginx configuration for the virtualhost, instead.

It's possible to disable some rules using modsecurity_rules inside specific server & location:

server {
    server_name wiki.example.com;
    modsecurity on;
    . . .

    location /api.php {
        modsecurity_rules '
            SecRuleRemoveById 941160
        ';
    }
}

The same is possible with Apache, too, as some Apache users may later find this question based on its title. With Apache, you can use SecRuleRemoveById / modsecurity_rules directives

  • inside VirtualHost and Location or LocationMatch:

    <VirtualHost *:443>
        ServerName wiki.example.com
        . . .
    
        <LocationMatch "^/api.php">
            <IfModule security2_module>
                SecRuleRemoveById 941160
            </IfModule>
            <IfModule security3_module>
                modsecurity_rules 'SecRuleRemoveById 941160'
            </IfModule>
        </LocationMatch>
    </VirtualHost>
    
  • or, although not recommended, even with .htaccess:

    <IfModule security2_module>
        <If "%{REQUEST_URI} =~ m#^/api.php#">
            SecRuleRemoveById 941160
        </If>
    </IfModule>
    
    <IfModule security3_module>
        <If "%{REQUEST_URI} =~ m#^/api.php#">
            modsecurity_rules 'SecRuleRemoveById 941160'
        </If>
    </IfModule>
    
Esa Jokinen
  • 43,252
  • 2
  • 75
  • 122
  • thank you for the suggestion! This is definitely clearer and more maintainable, without having to mess around with custom rule IDs. I have another question, but it's more of a general nginx config question. I could ask this elsewhere. With these new location blocks, I need to duplicate some configuration in order for my server to still serve these routes dynamically, and not give a 404 after ignoring the ModSec rule. See the comments in my config here: https://paste.victor.computer/By-xY5Ts8 – nnyby May 28 '20 at 20:07
  • It's best you ask another question on that! – Esa Jokinen May 28 '20 at 20:09
3

The answer is to use REQUEST_HEADERS:Host with chain, like this:

 SecRule REQUEST_HEADERS:Host "wiki.example.com" \
     "id:1017,\
     phase:2,\
     pass,\
     nolog,\
     chain"
     SecRule REQUEST_URI "@beginsWith /api.php" \
         "ctl:ruleRemoveById= 941160"
Esa Jokinen
  • 43,252
  • 2
  • 75
  • 122
nnyby
  • 298
  • 3
  • 5
  • 16