Forum Discussion

forsan's avatar
forsan
Icon for Altostratus rankAltostratus
May 12, 2014

Invalidate cookie on klient side

Hi,

I have an issue with a client cookie that are causing some issues. To avoid pushing out a new application deploy in production I like to do a fix in the BigIP until we have the next maintenance where the application is patched.

I found an example in this forum that I have modified. The cookie I like to modify exists in two different versions with the same name. So I need to check some parameters in the cookie to make sure that its the correct cookie.

Name: METRICS

Domain: .bar.com

Path: /

I have this iRule that I have one issue with. With I try to do a match class to the Path to be "/" I get the following error:

01070151:3: Rule [/Common/METRIC-cookie] error: Unable to find value_list (/) referenced at line 4: [class match [HTTP::cookie "Path"] eq "/"]

when HTTP_REQUEST {  
     Check the User-Agent string 
    if { ([HTTP::cookie exists "METRICS"] && [class match [HTTP::cookie "Domain"] eq ".bar.com"] && [class match [HTTP::cookie "Path"] eq "/"])} {  

        Set a variable to check the cookie in the response 
       set check_cookie 1 

    } else { 

        Set a variable to check the cookie in the response 
       set check_cookie 0 
    } 
 } 
 when HTTP_RESPONSE { 

     Check if cookie exists 
    if { $check_cookie && [HTTP::cookie exists "METRICS"]}{ 

        Update cookie expiry time 
       HTTP::cookie expires METRICS 1388534400 
    } 
 }
  • There are a few important reasons why the above doesn't work.

    1. Most important, the domain and path attributes of a cookie are only available in the Set-Cookie header, and then only available in an HTTP response. There's no way to tell what those values are in the request.

    2. I've seen this functionality change a few times over the years, but in general:

      • The HTTP::header command will only return the name of the last Set-Cookie header.

      • The HTTP::cookie command will only return the first cookie value if two cookies have the same name.

    For this reason, I've taken a significantly more manual, brute force approach. In the following iRule I'm inspecting the raw response TCP payload for the METRICS Set-Cookie data:

    when SERVER_CONNECTED {
        TCP::collect
    }
    when SERVER_DATA {
        if { [TCP::payload] contains "Set-Cookie: METRICS=" } {
    
             grab the start/end indices of all METRICS Set-Cookie headers
            set indices [regexp -all -inline -indices {Set-Cookie: METRICS=[^>]+?\n} [TCP::payload]]
    
             loop through the Set-Cookie indices
            foreach idx $indices {
    
                 find the start and length of each METRICS Set-Cookie header
                set start [lindex $idx 0]
                set len [expr { [lindex $idx 1] - $start + 1 }]
    
                 if the METRICS Set-Cookie header contains the specified domain attribute
                if { [string range  [TCP::payload] $start [lindex $idx 1]] contains "domain=domain.com" } {
    
                     find the start, end, and length of the expires property inside this Set-Cookie header
                    set expires [regexp -all -inline -indices {expires=[^>]+?;} [string range [TCP::payload] $start [lindex $idx 1]]]
                    foreach exp $expires {
                        set newstart [lindex $exp 0]
                        set newend [lindex $exp 1]
                    }               
                    set newstart [expr { $start + $newstart }]
                    set newend [expr { $start + $newend }]
                    set newlen [expr { $newend - $newstart + 1 }]
    
                     replace this expires property inside the TCP payload
                    set datestring [clock format "1388534400" -format "%a, %d-%b-%Y %T GTM" -gmt TRUE]
                    TCP::payload replace $newstart $newlen "expires=${datestring};"
                }
            }
        }
    
         release the payload
        TCP::release
    }