F5 irule Extracting data from the HTTP post payload

In the realm of application delivery, iRules offer a powerful mechanism for customizing traffic management and shaping user experiences. Today, we'll explore a practical iRule that seamlessly extracts valuable information from HTTP POST payloads, like form fields,jason payload also extract IP from the HTTP header X-Forwarded-For

Description:

    Below is the specific irule i wrote for a client where he needs to validate the client ip geo location and validate a parameter and its value in HTTP Post request body . The request is proxied via another Load balancer with X-Forwarded-For enabled.

Journey

Initially i started with the below irule to extract the parameter "transid" and its value from the HTTP Post payload.

when HTTP_REQUEST {
    if { [HTTP::method] eq "POST" } {
        # Get the POST payload data
set post_payload [HTTP::payload]
foreach x [split [string tolower $post_payload] "&"] {
if { $x starts_with "transid=" } {
    set transid [lindex [split $x "="] 1]
        }
    }
     log local0. "MY Transactin id number is $transid"
}
}

Next i used below irule to extract the X-Forwarded-For value and check the Geo location details and check the allow list in my datagroup list, the datagroup list contains two letters of country code eg:US,IN

when HTTP_REQUEST {
if { [HTTP::header exists "X-Forwarded-For"] } {
set client_ip [HTTP::header value "X-Forwarded-For"]
set fromCountry [whereis $client_ip country]
if { ( [class match $fromCountry equals example_datagroup]) }{
log local0. "Attacker IP in XFF [HTTP::header X-Forwarded-For] and from $fromCountry" 
  }
 }
}

Final irule

Based on above two irules i wrote the below irule to extract a parameter from the HTTP Post Body form request and validate the X-Forwarded-For IP Geo location

when HTTP_REQUEST {
  if { [HTTP::method] eq "POST" && [class match [HTTP::path] equals myurl-DG] } {
  if { [HTTP::header exists "X-Forwarded-For"] } {
    set client_ip [HTTP::header value "X-Forwarded-For"]
    set fromCountry [whereis $client_ip country]   
            if { ![class match $fromCountry equals geo-DG] }{
           set post_payload [HTTP::payload]
           foreach x [split [string tolower $post_payload] "&"] {
           if { $x starts_with "tranid=" } {
           set tranid [lindex [split $x "="] 1]
           if { ![class match $mid equals tranvalue-DG] } {
         local0. "DROPPING Request from country $fromCountry with TransID value $tranid"
                            drop
                        }
                    }
                }
            }
        }
    }
}

Using HTTP collect

For some reason the above irule didnt work for some traffic so i used below irule 

when HTTP_REQUEST {
set client_ip [IP::client_addr]
set country [whereis $client_ip country]
    if { [HTTP::method] eq "POST" && [class match [HTTP::path] eq url_dg] && $country ne "IN" } {
        HTTP::collect [HTTP::header Content-Length]
    }
}
when HTTP_REQUEST_DATA {
    set mid "unknown"
    foreach x [split [string tolower [HTTP::payload]] "&"] {
        if { $x starts_with "mid=" } {
            set mid [lindex [split $x "="] 1]
    if { ![class match $mid equals mid_value] } {
    log local0. "DROPPING Request from country $country with MID value $mid"
         drop
        }
    }
}
}

Consultion:

This artile gives an overview to extract the datas from the HTTP POST request payload or body request and either validate or log the value, also you will get an idea to extract the IP from the Http Header X-Forward-For and validate with a datagroup or geo location.

No Comment
Add Comment
comment url