Removing "www." causes problems when creating cookies for www.example.com and example.com
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | base system |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
The problem comes when trying to create cookies in custom/contrib module under the same cookie domain as the Drupal session, which is the cookie_domain defined at PHP level.
Being able to create cookies under the same domain as the Drupal session, makes it possible to share the cookies for the same exact sites as the Drupal session.
The "www." part of the domain cookie is stripped out in conf_init() since this patch, like this:
<?php
if (strpos($cookie_domain, 'www.') === 0) {
$cookie_domain = substr($cookie_domain, 4);
}
?>So there's no way for a site to use different cookie_domains for www.example.com and example.com. Both will blindly become example.com.
This is often no problem for the Drupal session, as both sites will likely be using the same sessions database. But if I need to use separate session tables for each site, then a session created for one site will need to be created for the other site, but Drupal will generate the same cookie name for both, and one login will override the other.
This scenario does not probably exist, as sites are using the same database for www.example.com and example.com, but the fact that "www." is stripped out from the cookie_domain causes problems for other cookies that attempt to be created under the same cookie domain as the session cookie.
Question: is there any reason to strip out "www." from the cookie_domain? If not, then would it be possible to remove the above mentioned lines from conf_init() ?
For reference, here's an issue for the Persistent Login module where I noticed this problem: #456334: Problems when cookie domains are www.example.com and subdomain.example.com (drupal removes www.).
If this is fixed for D7, then pleas consider backporting to D6. Thank you

#1
I've tried to research a little more, trying to figure out where's the origin of the code that removes "www." from the cookie domain. And I think I've found it:
http://drupal.org/node/108663#comment-490298
Well, I think that's ok when Drupal generates the cookie domain, which may be good enough for the average site. But current implementation does not allow a site to define different cookie domains for www.example.com and example.com. Worst, if you have 2 sites, say www.example.com and xxx.example.com, then the first cookie domain becomes example.com and the second xxx.example.com, but the browser will send all the cookies defined for www.example.com to xxx.example.com, which is a problem.
Aside from session cookies, almost no one else is using the cookie domain to create cookies, in other core components (has_js or comment module cookies), or custom/contrib modules. But this is a problem because these cookies cannot be shared with other sites that use the same cookie domain. When no domain is specified when creating a cookie, the browser will take the one that's currently in the URL. If something needs to share the cookie between sites, it needs to use the cookie domain.
But if "www." is removed from the cookie domain, then we have a problem.
Maybe the solution would be to only remove "www." from the cookie domain when it has not been explicitly defined in settings.php ? That would cover the default site layout (www.example.com + example.com is the same site), but would allow other layouts, such as www.example.com + xxx.example.com, or even www.example.com + example.com as different sites.
#2
It seems this would also be true if you have static files at static.example.com and the main domain at www.example.com.
It will set the cookie as .example.com and clients will send the session cookie for each static file request, when one of the supposed advantages of a static file subdomain is not sending cookies.
#3
@brianmercer
Yes it does. http://developer.yahoo.com/performance/rules.html#cookie_free
I really don't understand why the code is in conf_init. And I don't understand why the behavior is not documented in settings.php.
IMO the cookie domain should be that from settings.php. If I choose to have www.example.com don't change it behind my back. If I have login problem like people describe, well, you have settings.php to set the cookie domain to example.com, nothing stops you to do so.
What it puzzles me is that there were people that said that could be a problem, but they were ignored.
I attach a patch against HEAD and one for D6
#4
Let's just move the www.- prefix and port stripping above, just below:
<?php$cookie_domain = check_plain($_SERVER['HTTP_HOST']);
?>
#5
Why removing the www. if there is no cookie domain set? If someone really wants that removed he sets the cookie domain without www.
Anyway, it needs work, cause as it's now, it ads a point before www. I changed the code to remove that, but the SESSID cookie it's still has a .www.example.com domain while has_js for example it works as it should. I tried to figure why is that, but I couldn't for now.
#6
@tic2000: the default setting (if you have not explicitly set $cookie_domain in settings.php) should be: take the host, remove the www prefix, remove port numbers, and add a "." in front. That's a sane default setting, that will work for most users.
On the other hand, if you explicitly set $cookie_domain, Drupal should use that as-is.
#7
Then I think all that block of code should be moved inside the else. If the $cookie_domain is explicitly set it won't contain the port number. If it does it's not Drupal's job to fix bad settings.
#8
@tic2000: that's what I was suggesting in #4.
#9
Patches with the suggested changes.
#10
The last submitted patch failed testing.
#11
#12
Code looks good to me. Now, site admins has the full potential to define cookie domains as they wish, which is great. :-D ...and if not if cookie domain is not explicitly defined in settings.php, it will work as before, so it seems good to go.
BTW, thanks a lot for the patch to D6.
#13
@brianmercer: my issue is the same as you but I am not using www on my site, leading me to having a shared cookie on my static subdomain. Also outlined in http://www.phpied.com/www-vs-no-www-and-cookies/.
I guess I will need to park a new domain!
#14
The last submitted patch failed testing.
#15
Patches in #9 re-rolled.
#16
The last submitted patch failed testing.
#17
Patch for D7 in #15 re-rolled.
Patch for D6 in #15 still applies.
#18
The last submitted patch failed testing.
#19
Oops! Patch in #17 was not relative to Drupal root. Sorry.
#20
The last submitted patch failed testing.
#21
Re-rolled.