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

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 
    } 
 }

1 Reply

  • 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
    }