Mod Security

Article Topics: Setup

General Information on ModSecurity & ModSececurity2

  • The ruleset(s) provided by ModSecurity/ModSececurity2 will affect NATS processes and these rules are enabled by default. These default ruleset(s) need to be disabled so they will not get used.

  • Host can create custom rules that only apply to things outside of NATS

  • Host's responsibility to ensure that these rules don't affect NATS functions on NATS domain & linkdomains

Example Custom Rules for ModSecurity2

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)arrow-up-right

You can create customized rules with modsecurity2, to rate-limit by ip, request vars being sent, etc. These are example rules that will rate-limit requests and prevent bot spam. You can use these rulesets as a reference, but be aware that you are responsible for your configuration and that you should NOT use the default rulesets provided by modsececurity2.

Member Signup Throttling

Rate-limit to 75 requests to signup/signup.php using the same password or email within a 10- minute period.

<Location /signup/signup.php>	
	# needs to be enabled to read POST data
	SecRequestBodyAccess On

	# jump to SecMarker if signup[password] variable is not passed in request
	SecRule ARGS:signup[password] "^$" "phase:2,id:'981041',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS1"	

    # set 'RESOURCE' to value of signup[password] if it is not blank
	SecRule ARGS:signup[password] ".*" "phase:2,id:'1',chain,t:none,nolog,pass"
    	SecAction initcol:RESOURCE=%{ARGS.signup[password]}

    # enforce an existing block
    SecRule RESOURCE:bf_block "@eq 1" \
            "id:2,phase:2,deny,\
			msg:'Password \"%{ARGS.signup[password]}\" blocked because of suspected brute-force attack'"

	# set or increase count of how many times a signup[password] value was used and have it expire after 600 seconds
	SecRule ARGS:signup[password] ".*" "phase:5,id:3,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"

    # check for too many requests for a single signup[password] value and block future requests that contain that value
    SecRule RESOURCE:bf_counter "@ge 75" \
        "id:4,phase:5,t:none,pass,\
        setvar:RESOURCE.bf_block,\
        setvar:!RESOURCE.bf_counter,\
        expirevar:RESOURCE.bf_block=600"
		
	# jump to this point if signup[password] is not passed in request
	SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS1



	# jump to SecMarker if signup[password:1:6:16:::password_check] variable is not passed in request
	SecRule ARGS:signup[password:1:6:16:::password_check] "^$" "phase:2,id:'981042',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS2"
		

    # set 'RESOURCE' to value of signup[password:1:6:16:::password_check] if it is not blank
	SecRule ARGS:signup[password:1:6:16:::password_check] ".*" "phase:2,id:'5',chain,t:none,nolog,pass"
    	SecAction initcol:RESOURCE=%{ARGS.signup[password:1:6:16:::password_check]}

    # enforce an existing block
    SecRule RESOURCE:bf_block "@eq 1" \
        "id:6,phase:2,deny,\
		msg:'Password \"%{ARGS.signup[password:1:6:16:::password_check]}\" blocked because of suspected brute-force attack'"

	# set or increase count of how many times a signup[password:1:6:16:::password_check] value was used and have it expire after 600 seconds
	SecRule ARGS:signup[password:1:6:16:::password_check] ".*" "phase:5,id:7,t:urlDecode,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"

    # check for too many requests for a single signup[password:1:6:16:::password_check] value and block future requests that contain that value
    SecRule RESOURCE:bf_counter "@ge 75" \
        "id:8,phase:5,t:none,pass,\
        setvar:RESOURCE.bf_block,\
        setvar:!RESOURCE.bf_counter,\
        expirevar:RESOURCE.bf_block=600"

	# jump to this point if signup[password:1:6:16:::password_check] is not passed in request	
	SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS2



	# jump to SecMarker if signup[email] variable is not passed in request
	SecRule ARGS:signup[email] "^$" "phase:2,id:'981043',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS3"
		

    # set 'RESOURCE' to value of signup[email] if it is not blank
	SecRule ARGS:signup[email] ".*" "phase:2,id:'9',chain,t:none,nolog,pass"
    	SecAction initcol:RESOURCE=%{ARGS.signup[email]}

    # enforce an existing block
    SecRule RESOURCE:bf_block "@eq 1" \
            "id:10,phase:2,deny,\
			msg:'Email \"%{ARGS.signup[email]}\" blocked because of suspected brute-force attack'"

	# set or increase count of how many times a signup[email] value was used and have it expire after 600 seconds
	SecRule ARGS:signup[email] ".*" "phase:5,id:11,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"

    # check for too many requests for a single signup[email] value and block future requests that contain that value
    SecRule RESOURCE:bf_counter "@ge 75" \
        "id:12,phase:5,t:none,pass,\
        setvar:RESOURCE.bf_block,\
        setvar:!RESOURCE.bf_counter,\
        expirevar:RESOURCE.bf_block=600"

	# jump to this point if signup[email] is not passed in request	
	SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS3



	# jump to SecMarker if signup[email:1:1:128:::email_check] variable is not passed in request
	SecRule ARGS:signup[email:1:1:128:::email_check] "^$" "phase:2,id:'981044',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS4"

	# set 'RESOURCE' to value of signup[email:1:1:128:::email_check] if it is not blank
	SecRule ARGS:signup[email:1:1:128:::email_check] ".*" "phase:2,id:'13',chain,t:none,nolog,pass"
    	SecAction initcol:RESOURCE=%{ARGS.signup[email:1:1:128:::email_check]}

    # enforce an existing block
    SecRule RESOURCE:bf_block "@eq 1" \
            "id:14,phase:2,deny,\
			msg:'Email \"%{ARGS.signup[email:1:1:128:::email_check]}\" blocked because of suspected brute-force attack'"

	# set or increase count of how many times a signup[email:1:1:128:::email_check] value was used and have it expire after 600 seconds
	SecRule ARGS:signup[email:1:1:128:::email_check] ".*" "phase:5,id:15,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"

    # check for too many requests for a single signup[email:1:1:128:::email_check] and block future requests that contain that value
    SecRule RESOURCE:bf_counter "@ge 75" \
        "id:16,phase:5,t:none,pass,\
        setvar:RESOURCE.bf_block,\
        setvar:!RESOURCE.bf_counter,\
        expirevar:RESOURCE.bf_block=600"
	
	# jump to this point if signup[email:1:1:128:::email_check] is not passed in request	
	SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS4
</Location>

Plus script Throttling

Rate-limit the *plus scripts (as well as approved,upgraded,duplicate, and submit scripts) to 75 requests from the same ip address within a 10 minute period

Affiliate Login Throttling

Rate-limit affiliate login attempts to 100, but also dynamically increase rate-limiting to 5 if there are more than 1000 login attempts within a 5 minute period

Last updated

Was this helpful?