Trigger js challenge/Captcha for ip reputation/ip intelligence categories

The F5 devices use brightcloud as a source for detected bad ip addresses but a lot of times categories like "Spam Sources" or "Windows Exploits" need to be stopped. This code provides compromise between security and availability.

Problem solved by this Code Snippet

 

Because some ISP or cloud providers do not monitor their users a lot of times client ip addresses are marked as "spam sources"  or "windows exploits" and as the ip addresses are dynamic and after time a legitimate user can use this ip addresses the categories are often stopped in the IP intelligence profile or under the ASM/AWAF policy.

 

To still make use of this categories the users coming from those ip addresses can be forced to solve captcha checks or at least to be checked for javascript support!

 

How to use this Code Snippet

  • Have AWAF/ASM and ip intelligence licensed
  • Add AWAF/ASM policy with irule support option (by default not enabled under the policy) or/and Bot profile under the Virtual server 
  • Optionally add IP intelligence profile or enable the Ip intelligence under the WAF policy without the categories that cause a lot of false positives,
  • Add the irule and if needed modify the categories for which it triggers
  • Do not forget to first create the data group, used in the code or delete that part of the code and to uncomment the Bot part of the code, if you plan to do js check and not captcha and maybe comment the captcha part !

Code Snippet Meta Information

  1. Version: 17.1.3
  2. Coding Language: TCL

Code

You can find the code and further documentation in my GitHub repository:

reputation-javascript-captcha-challlenge/ at main · Nikoolayy1/reputation-javascript-captcha-challlenge

 

 

when HTTP_REQUEST {

# Take the ip address for ip reputation/intelligence check from the XFF header if it comes from the whitelisted source ip addresses in data group "client_ip_class"

if { [HTTP::header exists "X-Forwarded-For"] && [class match [IP::client_addr] equals "/Common/client_ip_class"] } {
    set trueIP [HTTP::header "X-Forwarded-For"]
} else {
    set trueIP [IP::client_addr]
}

# Check if IP reputation is triggered and it is containing "Spam Sources"

  if { ([llength [IP::reputation $trueIP]] != 0) && ([IP::reputation $trueIP] contains "Spam Sources") }{ 
    
    
       log local0. "The category is [IP::reputation $trueIP] from [IP::client_addr]"


# Set the variable 1 or bulean true as to trigger ASM captcha or bot defense javascript
       
       set js_ch 1
       
    
} else {
    
    set js_ch 0
    
}


#  Custom response page just for testing if there is no real backend origin server for testing

    if {!$js_ch} {
    
       HTTP::respond 200 content {
      <html>
         <head>
            <title>Apology Page</title>
         </head>
         <body>
            We are sorry, but the site you are looking for is temporarily out of service<br>
            If you feel you have reached this page in error, please try again.
         </body>
      </html>
      
       }
       
    }

}


#  when BOTDEFENSE_ACTION {

    # Trigger bot defense action javascript check for Spam Sources
    
  #    if {$js_ch && (not ([BOTDEFENSE::reason] starts_with "passed browser challenge")) && ([BOTDEFENSE::action] eq "allow") }{
    

#        BOTDEFENSE::action browser_challenge
          
  #    } 
    
#  }

 

when ASM_REQUEST_DONE {

 

# Trigger ASM captcha check only for users comming from Spam sources that have not already passed the captcha check (don't have the captcha cookie)

    if {$js_ch && [ASM::captcha_status] ne "correct"} {
    
       set res [ASM::captcha]
       
           if {$res ne "ok"} {
                log local0. "Cannot send captcha_challenge: \"$res\""
           }

    }
}

 

Extra References: 

 

BOTDEFENSE::action

ASM::captcha

ASM::captcha_status

 

Updated Feb 15, 2025
Version 6.0
  • Thanks for sharing Nikolay! I like the idea of providing an additional layer of security for certians set of users. Might as well try it out!