Forum Discussion

MW1's avatar
MW1
Icon for Cirrus rankCirrus
May 02, 2018

Match content in HTTP request and response - and block if value does not match

All, Been asked to implement a temporary fix for a web site until the server side fix can be written. The need is to query a soap POST request coming in to a web site on a specific URI, decode the authentication header in the request and perform a look up in a datagroup to find a mapped value, and match the web service call in the body of the POST request. If the request is one of the calls needing to be filtered then inspect the response back from the server and match a string in it to ensure it contains the mapped value from the datagroup, and if not block the server response.

I have the inbound working fine and set a variable "fixwc" if the inbound request matches the web service call that needs to be match and the "orgstring" variable as the string to match in the response, however the match on the server response using HTTP::collect does not work and appears if I write the payload to the log file to be only the first few lines of the response. I have adjusted the irule to use stream which does match successfully but I cannot see how to block the response if the string does not match.

Below is the snippet from the irule with the stream match -- can anyone advise if there is a way to stop the response being sent to the end user if the stream does not match or do I need to go back to HTTP:collect and try to work a way to capture the full server response?

 check server response contains matching orgstring otherwise drop request         
when HTTP_RESPONSE {
      STREAM::disable
    if {$fixwc eq "1"} {
      if { [HTTP::header value Content-Type] contains "text" } {
        STREAM::expression @$orgstring@
        STREAM::enable
}
}
}

 if match allow request - else block response     
when STREAM_MATCHED {

     log local0. "Temp fix-irule OrigID correct for request -- [STREAM::match]"
      }

For reference this was the section using HTTP:collect

 check server response contains matching orgstring otherwise drop request         
when HTTP_RESPONSE {
    if {$fixwc eq "1"} {
         Trigger collection for up to 1MB of data
        if {[HTTP::header exists "Content-Length"] and [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
}
}
}

 if match allow request - else block response     
when HTTP_RESPONSE_DATA {
        if { [string match  $orgstring [HTTP::payload]] } {
        log local0. "Temp fix-irule matched OrgString - allowing response)      
        return
        }{
        else discard
        log local0. "Temp fix-irule failed to match OrgString - dropping response"
    }
    }

2 Replies

  • I should just advise with regards to my comment "if I write the payload to the log file to be only the first few lines of the response" I have just read that the local log output is limited to the first ~1000bytes - using the HTTP Payload as a HTTP response in the irule when the match fails I do see the string in there, so the approach using HTTP::collect and match string issue appears to be simply the match command is not reading further enough down the response...totally confused currently!

     

  • Managed to resolve myself - Just to advise found I needed to switch

    if match allow request - else block response
    when HTTP_RESPONSE_DATA {
            if { [string match  $orgstring [HTTP::payload]] } {
            log local0. "Temp fix-irule matched OrgString - allowing response)      
            return
            }{
            else discard
            log local0. "Temp fix-irule failed to match OrgString - dropping response"
        }
        }
    `
    
    
    To be :
    
    
    `  if response data contains match allow request - else block response     
    when HTTP_RESPONSE_DATA {
                if { [HTTP::payload] contains $orgstring  } {
            HTTP::release
                    log local0. "Temp fix-irule match HomeOrg $homeorg to EnterpriseOrg $orgstring allowing request"
            }
            else {
                    HTTP::respond 500 content BLOCKED
                    log local0. "Temp fix-irule HomeOrg $homeorg to EnterpriseOrg $orgstring does not match -- dropping request"
        }
        }