ASM Proactive bot detection – Selective URLs

I would love to say that all URLs are created equal but that is not always the case. The same could be said about applying a security policy. Sometimes the logic behind one URL needs to be completely different. With the power of ASM + iRules, we can kick that logic up a notch.

when RULE_INIT {
  # Friends don't let friends log in production.
  # Logging off=0, Logging on =1
  set static::DEBUG_LEVEL 0
  }
when BOTDEFENSE_ACTION {
        if {[HTTP::uri] ends_with "/faq"} {
            if { $static::DEBUG_LEVEL == 1} { 
            log local0.alert "Allowed [HTTP::header User-Agent] to access [HTTP::uri]"
            log local0.alert "*************************************"
            log local0.alert ""
            log local0.alert "" }
            BOTDEFENSE::cs_allowed true
            set res [BOTDEFENSE::action allow]
        }   
        # EXAMPLE 2: Instead of blocking the request with TCP RST, respond with a
        # blocking-page
        if {[BOTDEFENSE::action] eq "tcp_rst" and [HTTP::uri] eq "/bloc_page_test" } {
                # if the custom_response action fails, the tcp_rst action will remain,
                # so we don't need to check the return string in this case
                BOTDEFENSE::action custom_response "sorry\ni am blocking you again\n"
        }
        if {not (([BOTDEFENSE::action] eq "allow") && ([BOTDEFENSE::reason] eq "valid cookie; no need to renew"))}
        {
          if { $static::DEBUG_LEVEL == 1} {
            log local0.alert "Got request from IP [IP::client_addr]"
            log local0.alert "UA is [HTTP::header User-Agent]"
            log local0.alert "Bot action is [BOTDEFENSE::action] because [BOTDEFENSE::reason]"
            log local0.alert "DeviceID is [BOTDEFENSE::device_id]"
            log local0.alert "*************************************"
            log local0.alert ""
            log local0.alert ""}
        }

        # EXAMPLE: Send a CAPTCHA challenge on the login page, and only allow the
        # login if the user passed the CAPTCHA challenge 

            if {[BOTDEFENSE::action] eq "allow"} {
            if {[BOTDEFENSE::captcha_status] ne "correct"} {
                if {[HTTP::uri] eq "/user/login"} {
                    set res [BOTDEFENSE::action captcha_challenge]
                    if {$res ne "ok"} {
                      if { $static::DEBUG_LEVEL == 1} {
                        log local0. "cannot send captcha_challenge: \"$res\"" }
                        BOTDEFENSE::action tcp_rst
                    }
                } elseif {[HTTP::uri] eq "/user/login"} {
                    set res [BOTDEFENSE::action custom_response {
                        login failed because you may not be human
                    }]
                    if {$res ne "ok"} {
                      if { $static::DEBUG_LEVEL == 1} {
                        log local0. "cannot send blocking page: \"$res\"" }
                        BOTDEFENSE::action tcp_rst
                    }
                }
            }
        }

}

As you can see, the power of iRules we can make decisions based on the following:

  • URI
  • DeviceID
  • TCP RST OR DROP
  • CAPTCHA

And that’s just how we do it at F5, stop the bad guys and look good doing it.

Best Regards,

BD