Forum Discussion

Nikoolayy1's avatar
Aug 16, 2022

Is it possible to insert HTTP payload in an ICAP reply or to change the status code?

Hello,

 

I see that some implementations of ICAP may by mistake not return an HTTP payload to the F5 Internal Virtual server but they have ICAP headers that a virus has been detected.

 

For now I found no way to manipulate this data as I do not seem be able to change the ICAP  status to "respond" with the ICAP events or to insert HTTP payload so to be able to match the ADAPT::result with the ADAPT_REQUEST_RESULT event on the real web virtual server so I am stuck.

 

 

https://clouddocs.f5.com/api/irules/ADAPT.html

https://clouddocs.f5.com/api/irules/ICAP.html

 

 

As of now I am thinking that without HTTP payload provided by the ICAP server in clear text (some hide the HTTP payload in the ICAP response as json like type) then the Adaptation Virtual server will not get the "respond" event From the F5 Internal Virtual Server as described in https://clouddocs.f5.com/api/irules/ADAPT__result.html that shows that there is HTTP response pange in the  reply from the external ICAP server but I decided to check with the community.

 

It would have neen a nice workaround if the ICAP server returns 544 for example response ICAP code as some ICAP servers can be configured what ICAP code to return and the F5 internal VS to be able with an ICAP irule to pass the code as a part ''ADAPT::result'' or to instert it as an HTTP payload Header in a iRule Generated Payload to the Adaptation Web VS that then can trigger again with an iRule for some some custom response page to be provided to the end user but maybe this is asking for too much hah.

  • Not an area of expertise for me, and after looking at all the ADAPT, ICAP, and IVS events/commands, my head is spinning... ðŸ˜«ðŸ˜«

    Will need to (eventually) mock up a scenario so I can better understand the iRules entry points around the workflow, which is better known to me as described in this lightboard lesson. It looks like TCP commands are allowed in ICAP events, so you could try a TCP::collect (not sure this specific action is allowed) and then modify in SERVER_DATA if it is...but again, never tried that and I haven't done anything outside of concepts with this.

    • Maybe with TCP::collect could trigger the ADAPT response if I insert HTTP in the ICAP reply at the TCP level. Not a bad idea.

  •  

    Hello,


    I have the same need and facing the same issue: need to change the response from the ICAP server.

    Here below part of the code I use in an iRule which works, but only when the communication uses HTTP/2.

     

     

    when ADAPT_REQUEST_RESULT {
    	#Save adapt result in var
    	set adaptresult [ADAPT::result]
    }
    
    #The HTTP_RESPONSE_RELEASE event is used as no communication
    #will go to the server when a virus is detected 
    when HTTP_RESPONSE_RELEASE {
    
    	switch -glob $adaptresult {
    		"respond" {
    			log local0. "ICAP - Malicious file uploaded - From: [IP::remote_addr] To: $hostname"
    
    			#Set the response
    			#It will overwrite the default response content sent by the ICAP server
    			set response "
    			  <html>
    					...
    			  </html>
    			"
    
    			#Send the response to the client
    			HTTP::respond 200 content $response
    
    			return
    		}
    
    		"abort" {
    			log local0. "ICAP - File too large uploaded - From: [IP::remote_addr] To: $hostname"
    
    			#Set the response
    			#It will overwrite the default response content sent by the ICAP server
    			set response "
    			  <html>
    				...
    			  </html>
    			"
    
    			#Send the response to the client
    			HTTP::respond 200 content $response
    
    			return
    		}
    
    		default {
    			return
    		}
    	}
    }

     

    It DOES NOT WORK when HTTP/1.x comes to the game.
    Problem is because "HTTP::respond" is not supported in event "HTTP_RESPONSE_RELEASE", even if works with HTTP/2. See: https://clouddocs.f5.com/api/irules/HTTP-RESPONSE-RELEASE.html

    I did open a case @F5 for investigation, and here below the answer:

    "From the previous escalation it has also been mentioned that there is no way at the moment ( meaning supported way ) to modify the response from the ICAP server before sending it to the client"

    I did try some rewritting at layer 4 level, and didn't manage to get a working solution.

    It feels like it's an impossible battle.

    • Nikoolayy1's avatar
      Nikoolayy1
      Icon for MVP rankMVP

      For me even with HTTP 1.1 this worked if the icap server returns HTTP data to trigger the "ADAPT_REQUEST_RESULT" event. The trick is in HTTP_RESPONSE_RELEASE to do a a redirect for example HTTP::respond 302 Location "http://www.domain.org" and this works (you can't have HTTP body in the event but HTT Headers are no problem ðŸ˜Ž ), you just need to host the web pages and it could on the same F5 VS if you add HTTP::uri condition in the HTTP_REQUEST event. 

      My issue was that if the ICAP server returns only ICAP data and no HTTP data then how trigger custom response page but it is not possible but for your issue there is a workaround.

      • Xavier_Baugniet's avatar
        Xavier_Baugniet
        Icon for Altocumulus rankAltocumulus

        Hello Nikoolayy1

         

        Indeed, your problem and mine are different.

        As I wrote HTTP::respond is not supported in HTTP_RESPONSE_RELEASE. Even if it looks to work, it shouldn't. I edited my previous post to add link for documentation where you can find the info.

        Sad thing is the F5 doesn't trigger an error when writing the iRule with this command, while it does if I use HTTP::redirect e.g..

        The best place would be in the ICAP_REPONSE event, see https://clouddocs.f5.com/api/irules/ICAP_RESPONSE.html, but I didn't yet found the way to modify the payload here.