Forum Discussion

Steve_245's avatar
Steve_245
Icon for Nimbostratus rankNimbostratus
Dec 15, 2016

Looking for Feedback/Efficiency on Cookie Removal

Background: We have a homegrown portal that users log in to and then launch applications from. This portal injects a ridiculous number of cookies into the client. One or more of these cookies prevent an application from working correctly. My iRule that I quickly made to 'fix' the issue is below. Since I cannot modify the response to expire the cookies I don't want since that will break other applications if they attempt to launch them, I have to scrub any of the cookies I don't want to get to this application on every incoming request.

Question(s):

1) Aside from fixing the portal (I want to replace it with APM...we'll see) is there another avenue I should be looking at to fix this besides an iRule?

2) Can my iRule be made more efficient through using switch or data groups? I couldn't figure out how to do that since I don't know of a way to do 'not equal' or not 'starts_with' within switch or how to get the data group syntax to work. There are more cookies I have to allow than included here. I shortened it.

when HTTP_REQUEST {
 set cookies [HTTP::cookie names]
 log local0. "Inbound cookies are $cookies" 
 foreach cookie $cookies {
  if { !($cookie starts_with "f5" or $cookie starts_with "" or $cookie starts_with "") }{
  HTTP::cookie remove $cookie
  log local0. "Removing cookie $cookie"
  }
 }
}
  • How about if you use a datagroup that has the Host header, or URI as data and a list of cookies to be removed. Match on host ( or URI ), retrieve list of cookies, loop through cookies and if matches list then remove cookie. URI-class: "/app1/user" => "cookie1;cookie2;cookie3"

    eg

    when HTTP_REQUEST
    if match class URI-class
      set cookies_remove [split $value ";"]
      foreach cookie $cookies
        if [lsearch $cookies_remove cookie]
          HTTP::cookie remove $cookie
        endif
      endforeach
    endif
    endwhen
    
  • Hi Steve,

    1.) Using an iRule is the only way to sanitize HTTP-request cookies. 2a.) If you need to whitelist less than 5 cookie names, then

    [if]
    is probably the best choice.

    when HTTP_REQUEST {
        foreach cookie [HTTP::cookie names] {
            if { not ( ( $cookie starts_with "f5" )
                    or ( $cookie starts_with "" ) 
                    or ( $cookie starts_with "" )
                    or ( $cookie starts_with "" )
                    or ( $cookie starts_with "" ) ) } then {
                HTTP::cookie remove $cookie
                 log local0. "Removing cookie $cookie"
            }
        }
    }
    

    2b.) If you need to whitelist more than 5 but less than 50 cookie names , then

    [switch -glob]
    is probably the best choice.

    when HTTP_REQUEST {
        foreach cookie [HTTP::cookie names] {
            switch -glob -- $cookie {
                "f5*" -
                "*" -
                "*" -
                "*" -
                "*" -
                "*" -
                "*" -
                "*" -
                "*" -
                "*" { 
                     Keep the cookie...
                }
                default {
                    HTTP::cookie remove $cookie
                     log local0. "Removing cookie $cookie"
                }
            }
        }
    }
    

    2c.) If you need to whitelist more than 50 cookie names , then

    [class]
    (aka. data-groups) is probably the best choice.

    ltm data-group internal DataGroup_Cookie_Whitelist {
        records {
            "f5" {}
            "" {}
            "" {}
            "" {}
            "" {}
            "" {}
            "" {}
            "" {}
            "" {}
            "" {}
        }
        type string
    }
    when HTTP_REQUEST {
        foreach cookie [HTTP::cookie names] {
            if { not ( [class match $cookie starts_with "DataGroup_Cookie_Whitelist"] ) } then {
                HTTP::cookie remove $cookie
                 log local0. "Removing cookie $cookie"
            }
        }
    }
    

    Note: The mentioned "best-choice" is purely based on performance data. Personal preferences may result in different "best-choices" 😉

    Cheers, Kai