Forum Discussion

Mango_LearnToUserF5's avatar
Mar 13, 2024

Irule Check payload contains

Hi Everyone,

 

i have a request payload like this:

POST /webconsole/api/security/auth/login HTTP/1.1
Host: 
Connection: keep-alive
Content-Length: 58
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
Accept: application/json, text/plain, */*
Content-Type: application/json
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (
OrganizationID: 
sec-ch-ua-platform: "Windows"
Origin: 
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: 
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: 

{"UserName":"test.org\\secadm01","Password":***************}

 

I want to create an irule to check with this URI: /webconsole/api/security/auth/login and client IP address is not X.X.X.X and the user login with user secadm will be blocked. other users with usernames not contain "secadm" would be ok. But this does not work. Please help advise

 

I write an irule as below:

 

when HTTP_REQUEST {
    if { [HTTP::path] equals "/webconsole/api/security/auth/login"} {
        if { [IP::addr [IP::client_addr] != 10.168.17.127] } {
             if { [HTTP::payload] contains "secadm" } {
                 drop
             }
        }
    }
}

  • Hello,

     

    You must first collect the payload when if matches the path then during the request_data event you can inspect the payload and do action

    From HTTP::collect example https://clouddocs.f5.com/cli/tmsh-reference/v15/modules/ltm/ltm_rule_command_HTTP_collect.html

     

    Might i also suggest instead of dropping the login attempt why not do a "fake" HTTP::respond (and log attempt) instead that looks similar to your app, so the actor is unaware that their attempt isnt actually going to the server, just a tought :)

     

    	when HTTP_REQUEST {
    
    	  if {[HTTP::method] eq "POST"}{
    	    # Trigger collection for up to 1MB of data
    	    if {[HTTP::header "Content-Length"] ne "" && [HTTP::header "Content-Length"] <= 1048576}{
    	      set content_length [HTTP::header "Content-Length"]
    	    } else {
    		set content_length 1048576
    	    }
    	    # Check if $content_length is not set to 0
    	    if { $content_length > 0} {
    	      HTTP::collect $content_length
    	    }
    	  }
    	}
    	when HTTP_REQUEST_DATA {
    	  # do stuff with the payload
    	  set payload [HTTP::payload]
    	}
  • Hi OCD_JAX,

     

    I found the problem, my i-rule is correct. The problem is about cookies and caching data on my browser, I guess. Because with the same rules, if i logined with incognito mode or a new browser, then i got block. But if i used the old browser that i used to logon success, the i-rule won't be triggered. When i clear all history data on the old browser, then it also got blocked.

     

    But i don't know how to check what exactly on the old browser prevent i-rule to work and can i somehow improve the i-rule to stop this situation when user got the caching data and cookie?

     

    Thank you for the idea on fake response, it is interesting.