Bug 11998

Summary: mod_usertrack spot_cookie() will not allow Apache to set a new cookie whose name is a substring of an existing cookie
Product: Apache httpd-1.3 Reporter: Mark Sweiger <msweiger>
Component: Other modsAssignee: Apache HTTPD Bugs Mailing List <bugs>
Severity: major    
Priority: P3    
Version: 1.3.26   
Target Milestone: ---   
Hardware: All   
OS: All   
URL: http://www.cisco.com

Description Mark Sweiger 2002-08-23 22:28:14 UTC
The function spot_cookie() in mod_usertrack does not allow Apache to set a new 
cookie that is a substring of another, already existent cookie.  The code that 
does the checking to see if the Apache cookie has previously been set is 
wrong.  Suppose the following directives are set:

CookieTracking on
CookieDomain .cisco.com
CookieName cpc
CookieExpires "25 years"

Suppose that another application has previously created a persistent cookie 
called "cpc3".  cpc3 will come across in the http Cookie: header string and the 
spot cookie code will fail as follows:

The code calls the C library strstr function 

strstr("cpc3=2039839", "cpc")

which finds the new cookie "cpc" string as a substring match on the first three 
characters of "cpc3".  This code wrongly assumes that we have found the cookie 
because it fails to check whether the next character in the string is an "=".  
Instead it just assumes it is and skips the next character, in this case "3", 
and uses the remainder of the cookie string as the value field, which is also 
wrong because in this case it has a leading "=".  I have verified the above 
scenario here at Cisco on a fresh install of Apache 1.3.26 and this is clearly 
a major bug.  In general, Apache will silently fail to set cookies if the 
cookie being set is a substring of an existing persistent cookie. 

The code for spot_cookie is included below:

static int spot_cookie(request_rec *r)
    cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config,
    const char *cookie;
    char *value;

    if (!dcfg->enabled) {
        return DECLINED;

    if ((cookie = ap_table_get(r->headers_in, "Cookie")))
        if ((value = strstr(cookie, dcfg->cookie_name))) {
            char *cookiebuf, *cookieend;

            value += strlen(dcfg->cookie_name) + 1;  /* Skip over the '=' */
            cookiebuf = ap_pstrdup(r->pool, value);
            cookieend = strchr(cookiebuf, ';');
            if (cookieend)
                *cookieend = '\0';      /* Ignore anything after a ; */

            /* Set the cookie in a note, for logging */
            ap_table_setn(r->notes, "cookie", cookiebuf);

            return DECLINED;    /* There's already a cookie, no new one */
    return OK;                  /* We set our cookie */
Comment 1 Mark Sweiger 2002-09-27 19:07:04 UTC
Is this bug ever going to be assigned to anyone?  There has been no activity for 
over 1 month.

Mark Sweiger
Cisco Systems
Comment 2 Jeff Trawick 2002-09-27 19:16:15 UTC
Just FYI regarding the PR database:

We don't have a paid staff to which PRs can be assigned to people
who are then compelled to fix it.  Instead, a volunteer will work on it 
if/when they become interested.

A working patch attached to the PR increases the likelihood that a
fix will be committed.
Comment 3 Cliff Woolley 2003-09-23 22:37:53 UTC

*** This bug has been marked as a duplicate of 16661 ***