Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Extracting specific information from an HTTP POST and logging it.

I am trying to log the IP address and usernames that are attempting to login to our web portal. I have the iRule mostly working, but I am having difficulty finding out how to extract certain pieces of the HTTP form rather than the whole thing. The fields in the form are UserID, EnteredUserId,and Password. Currently with the script below I get the following message in my LTM log file ": domain=&UserID=Nate10&EnteredUserID=Nate10&Password=PasswordRemoved has attempted to login from 172.xxx.xxx.xxx:61562." For security reasons I would like to just log the UserID and EnteredUserID as well as have a variable that can be toggled on/off to log the password for debugging and troubleshooting. I have tried adding a couple of different scripts to mine that I have seen in other posts, but nothing seems to work. Any ideas?

when HTTP_REQUEST { if { [HTTP::method] equals "POST" } { if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576} { set content_length [HTTP::header "Content-Length"] } else { set content_length 1048576 } HTTP::collect $content_length } } when HTTP_REQUEST_DATA { set client [IP::client_addr]:[TCP::client_port] set url [HTTP::header Host][HTTP::uri] set HTTP_METHOD [HTTP::method] set HTTP_PAYLOAD [HTTP::payload] log local0. "This is a test message $url $client" if {($url contains "/servlet/Login")} { log local0. "$HTTP_PAYLOAD has attempted to login from $client" } }

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

The simplest way is to use findstr on the payload

set user [ findstr [HTTP::payload] "user=" 5 & ]

If you know where the text is then you can also use string range

0
Comments on this Answer
Comment made 1 week ago by Pete White

Another point is that you shouldn't copy HTTP::payload to a variable as the payload could be a number of MB in size so you are wasting memory. Just use [HTTP::payload] unless you have a specific need to only work on a copy of it.

0
Comment made 1 week ago by nshelton85 2

What does the "5 &" do? I am relatively new to coding.

0
Comment made 1 week ago by Pete White

5 tells it to skip 5 characters from the start of the match string ( so it doesn't show you the user= text. For instance if your form field name was username then you would skip 9 ) and & tells it to stop matching - & is the end string for HTTP data.

0
Comment made 1 week ago by nshelton85 2

Thank you. using the example "set user [ findstr [HTTP::payload] "user=" 5 & ]" did exactly what I needed it to. I also cleaned up the script where I was storing the payload of the POST as a variable. Do I need to have an "Else" statement or anything at the end in case the virtual server receives an HTTP POST for another URL, or will the script as it is currently not block that request from going through?

when HTTP_REQUEST { if { [HTTP::method] equals "POST" } { if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576} { set content_length [HTTP::header "Content-Length"] } else { set content_length 1048576 } HTTP::collect $content_length } } when HTTP_REQUEST_DATA { set LogPassword "0" set client [IP::client_addr]:[TCP::client_port] set url [HTTP::header Host][HTTP::uri] set HTTP_METHOD [HTTP::method] set EnteredID [ findstr [HTTP::payload] "EnteredUserID=" 14 & ] set UserID [ findstr [HTTP::payload] "UserID=" 7 & ] set UserPassword [ findstr [HTTP::payload] "Password=" 9 & ] if {($url contains "/servlet/Login") and ($LogPassword>0)} { log local0. "$client has attempted to login to Commpilot with UserID=$UserID EnteredUserName=$EnteredID Password=$UserPassword." } if {($url contains "/servlet/Login") and ($LogPassword<1)} { set UserPassword "*****" log local0. "$client has attempted to login to Commpilot with UserID=$UserID EnteredUserName=$EnteredID Password=$UserPassword." } }

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

You can try this:

set user [ URI::query ?[HTTP::payload] user ]

URI::query search the query string in a URI (starting with ?), then search the parameter user and return the value.

As standard POST content format is the same as a query string, add a ? before payload to use URI::query command...

0
Comments on this Answer
Comment made 1 week ago by nshelton85 2

Both suggestions worked.

0