Chris Hawkins Chris Hawkins - 13 days ago 6x
HTTP Question

modsecurity create rule disable GET request

I want to create a mod security2x rule that will block the GET request to a specific URL.

for example I want to block the URL with the GET in the header: ''

I've never made a rule within modsecurity, and not sure this will work with anomaly detection mode.

This would be an example of the GET request:


This is what I have so far:
SecRule ARGS "" phase:2,log,deny,id:'1234',msg:'403 Access Denied'


You want something like this:

SecRule REQUEST_URI "@streq /secure/bla/test/etc/" \
     "phase:1,id:1234,t:none,t:urlDecode,t:lowercase,t:normalizePath,deny,status:403,msg:'403 Access Denied,chain'"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase"

You need to chain two rules together as you want to check two conditions (path is /secure/bla/test/etc/ and method is GET).

If you want to add a third rule to check the host (e.g. if you have multiple virtual hosts and this URL is valid for GET requests on some of them), then you can:

SecRule REQUEST_URI "@streq /secure/bla/test/etc/" \
     "phase:1,id:1234,t:none,t:urlDecode,t:lowercase,t:normalizePath,deny,status:403,msg:'403 Access Denied,chain'"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase,chain"
         SecRule SERVER_NAME "@streq"

Or alternatively you can use REQUEST_URI_RAW which will include the protocol and hostname as well as the resource requested:

SecRule REQUEST_URI_RAW "^https?://" \
     "phase:1,id:1234,t:none,t:urlDecode,t:lowercase,t:normalizePath,deny,status:403,msg:'403 Access Denied,chain'"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase" 

You'll notice I've also added quite a few transformation functions (the t: bits) to help avoid people trying to get around this rule (e.g. with a path like /secure/bla/TEST/../test/etc/).

All of this is covered in the reference manual: but does take a bit of practice to get used to I'll admit!

Anomaly detection mode simple means rules that might fire for valid requests do not blocked immediately but instead, assigned a score and if the total score of all the rules for that request is above a certain threshold then it blocks, if not it doesn't. This allows for "noisy" rules to still be included but to be ignored unless lots of noisy rules all fire for a request, or if one important rule is fired.

There is nothing to stop you explicitly blocking with the "deny" option as I have done above - even in anomaly detection mode. This rule seems fairly safe from ever firing accidentally for a legitimate request (once you have tested it works!) so I would just go from straight blocking as I have done above. The alternative is to replace deny with block,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score} which will have the same effect when the score is checked later but in my mind needlessly complicates the readability of the rule since it will always block anyway.

Anomaly scoring versus traditional scoring is covered in more detail in this blog post: