HTTP::cookie incorrectly marks a insecure cookie as secure if followed by another secure cookie [10.2.4]
We have a public application that failed a security audit when some cookies did not have the secure flag. We had an irule in place to force all cookies in the response to have the secure flag, but it would occasionally fail. [LTM 10.2.4]
It turns out that if a list of cookies is being acted on, it incorrectly thinks one is already secure. This is a test page:
$cookie_name1 = 'ASP.NET_SessionId'; $cookie_value1 = 'xxxxxz45r1jqjr45qpwuw0fn';
$cookie_name2 = '.reqid'; $cookie_value2 = 'yyyyy9cba1f34757a3e82a06587ec3c1';
$cookie_name3 = '.foobar'; $cookie_value3 = 'zzzzzzcba1f34757a3e82a06587ec3c1';
setcookie($cookie_name1, $cookie_value1,0,"/","",0,1); setcookie($cookie_name2, $cookie_value2,time()+3600,"/","",1,1); /* expire in 1 hour / setcookie($cookie_name3, $cookie_value3,time()+3600,"/","",0,1); / expire in 1 hour */
?> Some content
This is the irule (with lots of extra logging):
when HTTP_RESPONSE {
List all cookies in response
log local0. "All cookies: [HTTP::cookie names]"
Log the full value of all Set-Cookie headers before any manipulation
foreach myHeader [HTTP::header values "Set-Cookie"] {
log local0. "Set-Cookie: $myHeader"
}
The traditional method of looping through each cookie and forcing to secure
foreach { cookieName } [HTTP::cookie names] {
log local0. "Working on: $cookieName currently [HTTP::cookie secure $cookieName]"
HTTP::cookie secure $cookieName enable
log local0. "After change: [HTTP::cookie secure $cookieName]"
}
Force it to work, because the above clause fails
if [HTTP::cookie exists "ASP.NET_SessionId"] {
Does the system think the cookie is already secure?
log local0. "Before: [HTTP::cookie secure ASP.NET_SessionId] [HTTP::cookie value ASP.NET_SessionId]"
uncomment these to work around failure of foreach above
HTTP::cookie secure "ASP.NET_SessionId" disable
log local0. "Between: [HTTP::cookie secure ASP.NET_SessionId] [HTTP::cookie value ASP.NET_SessionId]"
HTTP::cookie secure "ASP.NET_SessionId" enable
log local0. "After: [HTTP::cookie secure ASP.NET_SessionId] [HTTP::cookie value ASP.NET_SessionId]"
}
}
I can see it fail in the logs:
info tmm[4884]: Rule secure_cookie_append_test : Set-Cookie: ASP.NET_SessionId=xxxxxz45r1jqjr45qpwuw0fn; path=/; httponly Note it isn't secure
info tmm[4884]: Rule secure_cookie_append_test : Set-Cookie: .reqid=yyyyy9cba1f34757a3e82a06587ec3c1; expires=Thu, 22-May-2014 19:58:39 GMT; path=/; secure; httponly
info tmm[4884]: Rule secure_cookie_append_test : Set-Cookie: .foobar=zzzzzzcba1f34757a3e82a06587ec3c1; expires=Thu, 22-May-2014 19:58:39 GMT; path=/; httponly
info tmm[4884]: Rule secure_cookie_append_test : Working on: ASP.NET_SessionId currently enable note it wrongly marks it as secure
info tmm[4884]: Rule secure_cookie_append_test : After change: enable
info tmm[4884]: Rule secure_cookie_append_test : Working on: .reqid currently enable
info tmm[4884]: Rule secure_cookie_append_test : After change: enable
info tmm[4884]: Rule secure_cookie_append_test : Working on: .foobar currently disable
info tmm[4884]: Rule secure_cookie_append_test : After change: enable
If, however, you don't send the second (secure) cookie, it works as intended.
info tmm[4884]: Rule secure_cookie_append_test : All cookies: ASP.NET_SessionId .foobar
info tmm[4884]: Rule secure_cookie_append_test : Set-Cookie: ASP.NET_SessionId=xxxxxz45r1jqjr45qpwuw0fn; path=/; httponly Note no secure flag
info tmm[4884]: Rule secure_cookie_append_test : Set-Cookie: .foobar=zzzzzzcba1f34757a3e82a06587ec3c1; expires=Thu, 22-May-2014 19:59:57 GMT; path=/; httponly
info tmm[4884]: Rule secure_cookie_append_test : Working on: ASP.NET_SessionId currently disable note it thinks it isn't secure
info tmm[4884]: Rule secure_cookie_append_test : After change: enable
info tmm[4884]: Rule secure_cookie_append_test : Working on: .foobar currently disable
info tmm[4884]: Rule secure_cookie_append_test : After change: enable
Am I not using the list of cookies properly? Is this a known issue anywhere? It took a freakishly long time to figure out, because in general it works as expected. The workaround is to specifically test the cookie, mark it as disabled, then enable it again.
Thanks.