For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

mghosh_170954's avatar
mghosh_170954
Icon for Nimbostratus rankNimbostratus
Sep 19, 2014

iRule POST data manipulation truncates the message

I have an iRule where I am intercepting an incoming HTTP POST request. Then matching a portion of the request in the input stream, manipulating it and then sending it on.

 

However, I noticed that in doing the manipulation on the POST message is truncating it.

 

What is the correct way of manipulating HTTP POST messages such that they are not truncated?

 

3 Replies

  • Depends on how you are manipulating. Are you doing a simple string match/replace? If so, a stream profile is probably a better solution.
  • Here's the iRule: when HTTP_REQUEST {   log local0. "URI: [HTTP::uri] - IP: [IP::client_addr] - Method: [HTTP::method]"   STREAM::disable   if { ( [HTTP::method] equals "POST" ) && ( [HTTP::uri] equals "/Process/POST" )  } {     log local0. "URI: [HTTP::uri] - IP: [IP::client_addr]"     STREAM::expression "@TestState.*@@"     STREAM::enable   } } when STREAM_MATCHED {   set url_string [STREAM::match]   log local0. "Input String: $url_string"   regexp {(TestState=)(.*)(&.*)} $url_string -> first url last   regsub -all {%25} $url % new_url   set replacement_string "${first}${new_url}${last}"   log local0. "Output String: $replacement_string"   STREAM::replace $replacement_string }
  • At a minimum, the STREAM process may not be updating the Content-Length header. Also, since you're not explicitly buffering the payload with an HTTP::collect, I believe the STREAM is only working on HTTP headers and any payload data that may fill the first TCP packet. Here's a version that specifically buffers and works on HTTP payload data:

    when HTTP_REQUEST { 
        log local0. "URI: [HTTP::uri] - IP: [IP::client_addr] - Method: [HTTP::method]"
    
        if { ( [HTTP::method] equals "POST" ) && ( [HTTP::uri] equals "/Process/POST" ) } {
            log local0. "URI: [HTTP::uri] - IP: [IP::client_addr]"
            HTTP::collect [HTTP::header Content-Length]
        }
    }
    when HTTP_REQUEST_DATA {
        set old_teststate [findstr [HTTP::payload] "TestState=" 0 "&"]
        regsub -all {foo} $old_teststate bar new_teststate
        set new_payload [string map "$old_teststate $new_teststate" [HTTP::payload]]
    
        HTTP::payload replace 0 [HTTP::payload length] $new_payload
    }