Forum Discussion

ralgar1_294065's avatar
ralgar1_294065
Icon for Nimbostratus rankNimbostratus
Sep 06, 2017

Inspect POST Request for Existence of Username Parameter

Is it possible to to check if a username has been provided in a POST request? Could this be done via HTTP::username command or would a HTTP::collect be needed to inspect the payload of the request? Would you be able to provide an example of how this might be done via an Irule.

 

  • Hi Ralgar1,

    to inspect post parameters you have to use HTTP::collect to become able to parse the POST-Request data. The

    [HTTP::username]
    and
    [HTTP::password]
    commands are designed to parse HTTP-BASIC authentication data.

    You may use the iRule below as a starting point for your own iRule...

    when RULE_INIT {
        set static::login_max_post_datasize 1024    ; (bytes)
    }
    when HTTP_REQUEST {
         Check for request to login page...
        if { [string tolower [HTTP::path]] ends_with "/login.aspx" } then {
             Check for POST request to login page...
            if { [HTTP::method] eq "POST" } then {
                 Check for existence of Content-Length header and enforce maximum POST data size.
                if { ( [HTTP::header value "Content-Length"] ne "" )
                 and ( [HTTP::header value "Content-Length"] <= $static::login_max_post_datasize ) } then {
                     HTTP::collect the HTTP body based on Content-Length header information.  
                    HTTP::collect [HTTP::header value "Content-Length"]
                     Set variable as signal for HTTP_REQUEST_DATA event.
                    set extract_login_data true
                } else {
                     Complain about request body size.
                    HTTP::respond 500 content "Request body does not exist or is too large" noserver "Content-Type" "text/html"
                }
            } else {
                 No POST request. Ignore the request...
            }
        } else {
             No Login page request. Ignore the request...
        }
    }
    when HTTP_REQUEST_DATA {
        if { [info exists extract_login_data] } then {
             Remove signal variable for subsequent requests on the same TCP connection.
            unset -nocomplain extract_login_data
             Extract the entire HTTP request body and escape it to become a HTTP::uri string (for easier parsings)
            set http_request_body "?[HTTP::payload [HTTP::header value "Content-Length"]]"
             Try to parse the username and password value from the HTTP request body.
            if { [catch {
                set username [URI::decode [URI::query $request_body username]]
                set password [URI::decode [URI::query $request_body password]]
            }] } then {
                 Unable to extract the and parse the username and password value from the HTTP request body.
                HTTP::respond 500 content "Unable to parse username and/or password from POST data" noserver "Content-Type" "text/html"
                return
            }
            if { ( $username ne "" ) 
             and ( $password ne "" ) } then {
                HTTP::respond 200 content "Username: \"$username\" | Password: \"$password\"" noserver "Content-Type" "text/html"
            } else {
                HTTP::respond 403 content "Username or Password is empty" noserver "Content-Type" "text/html"
            }
             Do whatever you need to do with the $username or $password variables...
        } else {
             Event was triggered by another iRule. Ignore the request...
        }
    }
    

    Cheers, Kai