33

I'm working on a site with multiple subdomains, some of which should get their own session.

I think I've got it worked out, but have noticed something about cookie handling that I don't understand. I don't see anything in the docs that explains it, so thought I would see if anyone here has some light to shed on the question.

If I just do:

session_start();

I end up with a session cookie like this:

subdomain.example.net

However, if I make any attempt to set the cookie domain myself, either like

ini_set('session.cookie_domain', 'subdomain.example.net');

or like

session_set_cookie_params( 0, "/", "subdomain.example.net", false, false);

I end up with a cookie for .subdomain.example.net (note the opening dot), which I believe means "match all subdomains (or in this case sub-subdomains).

This seems to happen with all my cookies actually, not just session. If I set the cookie domain myself, it automatically has the dot prepended, meaning this domain and all subs of it. If I don't set the domain, then it gets it right by using only the current domain.

Any idea what causes this, and what I can do to control that prepending dot?

Thanks!

Eli
  • 97,462
  • 20
  • 76
  • 81
  • You don't have to control the leading dot because it's just *ignored* by the browser, as per RFC 6265, which is what every modern browser implements. So just don't think about the leading dot. Apart from that, set the cookie domain explicitly or set it to an empty string to limit it to the current request host. The library https://github.com/delight-im/PHP-Cookie has some convenient controls for that. – caw Jul 13 '16 at 00:05

6 Answers6

23

PHP's cookie functions automatically prefix the $domain with a dot. If you don't want this behavior you could use the header function. For example:

header("Set-Cookie: cookiename=cookievalue; expires=Tue, 06-Jan-2009 23:39:49 GMT; path=/; domain=subdomain.example.net");
Brian Fisher
  • 23,519
  • 15
  • 78
  • 82
  • 17
    If you read all of RFC 6265, you'll realize that the only proper way to have a "host-only" cookie, is to NOT set the domain attribute. http://tools.ietf.org/html/rfc6265#section-5.4 – stolsvik Nov 14 '11 at 13:13
  • 2
    "the only proper way to have a "host-only" cookie, is to NOT set the domain attribute" Not specific to PHP, but this helped me solve an issue when we were switching from HOST only cookies to x-subdomain cookies and I was trying to delete the host only cookie in javascript by specifying the full domain, and JavaScript was prepending a dot which caused the domain of the existing cookie not to match, and as a result not be removed. – Scott Jungwirth Jun 30 '14 at 18:32
22

If you run your PHP script under "http://subdomain.example.net", don't use the domain parameter:

setcookie('cookiename','cookievalue',time()+(3600*24),'/');

You will get a cookie with "subdomain.example.net" (and not ".subdomain.example.net")

Kevin Campion
  • 2,223
  • 2
  • 23
  • 29
  • 1
    What's the difference between an explicit domain set to subdomain.example.net and one that is not set? – Pacerier Jun 07 '13 at 00:54
  • if you set it, you get a dot in front which matches all subdomains, instead of only matching the current subdomain only – troseman Jul 26 '13 at 20:48
15

If you read all of RFC 6265, you'll realize that the only proper way to have a "host-only" cookie is to NOT set the domain attribute.

https://www.rfc-editor.org/rfc/rfc6265#section-5.4

Community
  • 1
  • 1
stolsvik
  • 5,253
  • 7
  • 43
  • 52
12

I realise this is an old question but I was having this problem and none of the answers above quite did it.

I wanted to set the session cookie for a subdomain, but also enable httponly and secure.

To avoid a leading . infront of the subdomain, Kevin and stolsvik are correct don't set the domain attribute.

So to do this and still be able to set httponly and secure mode, set the domain to NULL as follows:

session_set_cookie_params(0, '/', NULL, TRUE, TRUE);

You will now have a session cookie, for a specific subdomain (without a leading .) with httponly and secure set to true.

Alex
  • 1,018
  • 1
  • 11
  • 21
2

This may help someone (i spent some hours to figure this out). After make the changes in the source files and before you test it, close your browser to properly destroy PHPSESSIONID in all domains and subdomains.

Hope this save some time!

  • 1
    You can also use the session part of Firebug if you want to manage the session cookies explicitly. – Eli Jan 24 '11 at 21:46
0

I was having a problem to set cookies on wordpress and this helped me, the domain value was the key to get it working in all the pages

$domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;

setcookie("cookie_name", 'cookie_value', 0, '/', $domain);
Gendrith
  • 196
  • 1
  • 4
  • 13