IE10 sharing cookies across subdomains by default - php

IE10 appears to handle cookies and subdomains differently than other major browsers (IE8, IE9, Firefox, Chrome, Safari).
We use subdomains extensively for test environments, e.g.:
user1.devel.example.com
user2.devel.example.com
qa.example.com
And our production environment lives at the top, e.g. example.com (and technically at www.example.com as well).
We use the php setcookie($name, $value, $expires) function naively (no explicit path or domain is specified) to set a cookie, and then clear cookies (when user logs out) by assigning an empty string to the value. This has always worked fine, and each unique subdomain used their own cookies.
IE10 now "shares" the cookie that was set in the TLD with all subdomains. The initial symptom we observed was that no one could log out of the subdomain. We've observed a few things:
Even though it shares the value, no subdomain is able to clear the cookie.
When the TLD clears the cookie, it is immediately removed from all subdomains as well.
Has anyone else observed similar behavior to how IE10 stores/applies cookies relative to subdomains? Is there any workaround, other than being explicit about which domain the cookie applies to when sending the initial Set-Cookie header?

I have just run into this issue.
Here is a link to someone exploring this bug/issue:
Cookies with and without the Domain Specified (browser inconsistency)
This also might be related:
Cookie set for subdomain, but IE Developer Tools show cookie at root domain. What am I missing?
My conclusion is that when setting a cookie from a non-www root domain ( http://sites.com ), in IE this is seen as a wildcard cookie for all subdomains. Chrome and Firefox do not show this behavior - they associate a cookie set from a non-www root domain as being associated only with that root.
I coded up example sites using .net webforms, IIS and my hosts file. I had 3 sites:
a.site.com, b.site.com and site.com. They all served cookies with the exact same name. Let's call it "ShoppingCart".
You can set multiple properties on cookies, including the domain the cookie should be associated with. I left this property to be defined/left undefined by .net. When Chrome received the cookie from each site, it displayed the domain of the cookie as being explicitly from the domain listed in the browser address bar. In IE this was not the case. IE treats the cookie from http://sites.com as being defined as ".sites.com" and according to the RFC for cookies this means it is accessible from all subdomains.
Also in IE, if multiple cookies are set with the same name, IE returns them to the server in the order they were set. So if I visit http://sites.com first and then visit http://a.sites.com and then refresh, IE views the cookie from http://sites.com as a valid cookie to send to the server in it's request for http://a.sites.com which is sent along with the cookie for http://a.sites.com, except the cookie for http://sites.com is the first in the list.
In .net, from what I've seen, cookies are generally accessed by keyname and not by index. So when the server side code attempts to access the value for the key named "ShoppingCart", it will grab the value for the first site that set the cookie value - here that would be http://sites.com.
In summary - don't use non-www domains when you have subdomains that all share the same cookie key names because, while Chrome/Firefox handle the domain association as you would expect, IE causes buggy behavior.
Edit--
Just to clarify for anyone reading this, I was using IE10 to explore this issue.

Super easy way to fix this if you have multiple PHP sites on a domain.
For example - if you have Wordpress on the root (example.com) and you have a custom PHP app on the subdomain (a.example.com) then either within your app or Wordpress you need to set a different SessionName.
Add the session_name() prior to your session_start() which should give two seperate names to the session and therefore not clash.
session_name('AppSession');
session_start();
Easy.

Yes, this is a known issues it seems, read here: http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx
They refer to this test: http://debugtheweb.com/test/cookieinherit.aspx and http://www.debugtheweb.com/test/cookieinherit.aspx

I am having same issue in IE 11.0.9600 for php session cookie: Internet Explorer is sending root domain cookies to all its subdomains. To solve this, I store the domain name in a session variable:
$_SESSION['URL'] = str_replace('www.', '', $_SERVER['HTTP_HOST']);
Then for every request, I check the session variable:
if ( str_replace('www.', '', $_SERVER['HTTP_HOST']) != $_SESSION['URL']) {
session_regenerate_id(true);
$_SESSION = array();
$_SESSION['URL'] = str_replace('www.', '', $_SERVER['HTTP_HOST']);
}
Then, when we move from the root domain to the subdomain, we will not be 'in' the same session.

Related

Set cookie to specific domains

I own a lot of subdomains, but only the main domain have SSL. On each subdomain there is a different website, and all are using the same CMS system, the same files and hosting (basicly it is redirects to the main domain and using PHP I show the site they want to see). I have one SSL to my main domain only. It won't work on subdomains obviously. So I thought to submit the form to the main domain from the subdomain using AJAX, but I guess it isn't safe, so I decided that I should use:
<iframe src="https://main.com/login.php?webid=958325&pageid=83985&hash=hjWR23grvw$%F$W"></iframe>
but the problem is the cookies. How can I create a cookie that will work on all subdomains, the main domain, and if it is possible, to some specific urls (that works the same way, but domain and not subdomain).
http://php.net/setcookie
The fifth and sixth parameter might interest you, which are respectively:
(5th) domain
(6th) secure
For example:
// This cookie will only be set to domain.com/folder if a secure connection exists and will expire once the browser closes.
setcookie('cookie', $variable, 0, 'folder/', 'domain.com', true);
To have cookie working on all subdomains you need to set cookie to .example.com but it wont work on example.com, so you may need to set two cookies.

Cookie is being seting to only one domainname but the website has multiple domain name

I have a website with two domain names which shows the same content from both domain names and it is also correct for sub-domain, but the problem is when I set a cookie for this website which is used in its sub-domain websites.
The cookie is being set only to one domain name, not for both.
What is the problem?
As you must know, a cookie can only be set for a domain from that domain (including its subdomains). And if your domains do not share a common superdomain, you need set each cookie for each domain separately.
You can do this with a script that on each domain that sets the cookie for you. But make sure to authenticate requests to these scripts so that only you can set the cookies.
Refer link
You can setup an API on a common domain to set cookies for all domains which want to access said cookie info. The common domain cookie would have namespace keys representing the domains, etc. and would do all the cookie reading/writing. Use XHR to access the common domain with params you wish to be placed into the common cookie. Just keep in mind Safari disables 3rd party cookies by default.
You cannot share cookies between two different domains, even if you own both of them.
SO has some posts regarding cross domain cookies, and other possible solutions:
Cross domain cookies
Cross-Domain Cookies
Cookies are not designed to be accessible for other domains
But there is always a workaround ;)
There are to method to achieve this
including 2 hidden iframes from different domains to set cookies with same value.
Ex. http://productforums.google.com/forum/#!topic/websiteoptimizer/aD4rZSoaKNo
using master and slave domain configuration
Example:
https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite
http://www.codeguru.com/csharp/csharp/cs_internet/article.php/c19417/Sharing-Cookies-Across-Domains.htm

PHP Cookies for multiple Domains

I want to create a cookie from one domain once the user is registered in PHP. and make this cookie accessible to 4 other domains not subdomain. I know that cookies are not designed to be accessible for other domains. For example I have set a cookies variable $user_email from domain www.firstdomain.com and want to access it in other domains like www.seconddomain.com, www.thirddomain.com etc. May be this can be done using PHP or JavaScript. Any idea please.
Thank you!
When searching the cookie list for
valid cookies, a comparison of the
domain attributes of the cookie is
made with the Internet domain name of
the host from which the URL will be
fetched. If there is a tail match,
then the cookie will go through path
matching to see if it should be sent.
"Tail matching" means that domain
attribute is matched against the tail
of the fully qualified domain name of
the host. A domain attribute of
"acme.com" would match host names
"anvil.acme.com" as well as
"shipping.crate.acme.com". Only hosts
within the specified domain can set a
cookie for a domain and domains must
have at least two (2) or three (3)
periods in them to prevent domains of
the form: ".com", ".edu", and "va.us".
Any domain that fails within one of
the seven special top level domains
listed below only require two periods.
Any other domain requires at least
three. The seven special top level
domains are: "COM", "EDU", "NET",
"ORG", "GOV", "MIL", and "INT".
The default value of domain is the
host name of the server which
generated the cookie response.
read up here.
you can load an iframe from a host which then reloads itself with the encoded cookie value in the segment part (after the #).
you can then access the document.location attribute from the parent window (hits the only thing that is accessible). decode it and pass it to your server doing an ajax request.
This could look like so.
xss.php (located on cookies.example.com):
<?php
$data = array(
'uid' => $_COOKIE['uid'],
'loginhash' => $_COOKIE['loginhash']);
header('Location: xss.php#'.urlencode(json_encode($data)));
for this particular case it does not need to be the hashtag! its just convinient for other situations. this can also be done in javascript.
another website embeds xss.php:
<iframe id="cookies" src="http://cookies.example.com/xss.php"></iframe>
you need to somehow delay the following of do it in a loop that stops after 5 seconds or something.
if(document.getElementById('cookies').location != 'http://cookies.example.com/xss.php') {
// read location, extract hashtag, json decode using javscript, there you have your user. send it to server for validation or whatever.
}
this teqnique is called xss recieving. it is for example utilised by facebook for all their javascript connect libraries.
a probably better way would be some sort of token exchanging protocol like openid.
amazon uses this too.
you can set up an openid provider (there are librarys available that can do that out of the box) and set it to auotmatically redirect back without user interaction. i have often seen openid protocol used for some other purposes just like cross domain communication.
As you have already said, a cookie can only be set for a domain from that domain (including its subdomains). And if your domains do not share a common superdomain, you need set each cookie for each domain separately.
You can do this with a script that on each domain that sets the cookie for you. But make sure to authenticate requests to these scripts so that only you can set the cookies.
I had solved exactly same problem (actually also for 4 domains). The only solution I've came up with was, to include 3 hidden iframes on the 'Successful login page' and those iframes just load www.domain1.com/register_session.php, www.domain2.com/register_session.php, etc....
As a parameter for register_session.php I use 'sid' which contains session ID:
session_id($_GET['sid']);
session_start();
This is actually for keeping session alive on all those domains but the same would be for your case with cookies.
I ve done some scripts to handle multi domain cookie :
https://code.google.com/p/mudoco/
if you want to access cookie within different domains so this can be done with the help of javascript trick. As cookie can be accessed within same domain.
Create cookie on user’s browser using JavaScript on your first domain.
Set the name of the window to whatever value of cookie you want to carry to another domain by using window.name.
Step 2 should be performed on every page of the domain which has created the cookie. It could be easily by calling a JavaScript file on all pages.
When you move to another domain, and want to access the above mentioned cookie value, access it by using window.name as window has not changed.
Create new cookie on this domain and assign this value to it.

session variables not carrying over from http://www.xxxx.com to http://xxxx.com

I was brought aware of this issue by some users on my website. A user many enter into their browser http://xxxx.com and then login. Then they may click on a link that brings them to http://www.xxxx.com it asks them to login again! Is this a known issue that anyone has encountered before? I tried googling it but im not sure if im using the wrong keywords or what because i cannot find anything related to this.
Thanks,
Ian McCullough
As far as your browser is concerned, www.xxxx.com and xxxx.com are different domains. The same-origin policy prevents accessing cookies across domains.
However, the browser is aware of subdomains, and a subdomain can access the cookies of a parent domain. So, if you want to make your cookie accessible to both xxxx.com and www.xxxx.com, just set your cookie on .xxxx.com and you'll be set.
When you set a cookie, you can optionally specify which domain the cookie is set for. If you don't, the cookie is particular to that hostname only, and thus if the cookie is set on www.example.com, it will only be returned by the browser on that hostname or below.
If, when setting the cookie, you set the domain to "example.com" it should work also on "www.example.com".
The problem is that the more specific cookie will override the less specific one, so if you've previously set a cookie on "www.example.com" it will continue to override the new one set for "example.com", rather than being replaced by it - you would first have to delete the one set for "www.example.com". It gets tricky since when the client returns a cookie to the server it doesn't say which hostname the cookie was set for.
People seem to be assuming you're using a cookie to perform authentication but are skipping what appears to be your root question. Trevor briefly touched on it, but still kept to the cookie concept. As far as http is concerned, www.xxxx.com and xxxx.com are different subdomains on the same top level domain. Hence, while they may be the same ip, same website, same everything, the browser request and the server's response are considered to be 2 separate domains/sites. Sessions are not shared across subdomains unless you have a separated session state (such as a SQL Session store, etc).
However, if you are using cookies for authentication, you can add a check for the cookie and rebuild a fresh session if the data in the cookie is valid (and sufficient to reconstruct session). Otherwise you'll have to separate session state from the process into a data store.
Check the domain of the cookie, when creating a cookie you can specify if it is for all sub domains, the root server, specific sub domain, etc. To handle all, the cookie would be for .example.com

PHP session id's differ

i am using php 5.2.8
i have index.html, which loads LOAD.PHP from IFRAME.
iframe src="load.php".....
i printed out load.php's session id.
then i ran another test.php, and printed out it's session id.
php session id's were different.
therefore, i cannot pass any session variables....
what is happening here ? this problem did not happen before, suddenly today it started happening.... however this problem still exists....its driving me nuts !
session.saved_path is same for both.... /var/php5, cookie path is same...
If PHP is creating a second session ID on the second load of the page, then it means that the first one was not passed back properly. Likely, the cookie is not being set for some reason. Things to check:
Test in multiple browsers?
Did you disable cookies in your browser somehow?
Is the iframe on a different domain or subdomain that might prevent cookie passing?
Install LiveHTTPHeaders or some other firefox add-in to check the cookies you are receiving
http://www.example.com will have a different sessionID than http://example.com
(not really an answer as your questions doesn't seem to me to have enough data to provice a certain answer, but rather a few things to check about)
The files are in the same domain and directory and the cookie are not limited to a different directory (i.e. path=/)? (note: they're not limited unless you tell that explicitly with session_set_cookie_params)
Is the browser sending the cookie (or are you maybe in "incognito mode")? If cookies don't work PHP will probably try to pass Session IDs in the QueryString and fail, if you go to test.php writing its name manually and not following a link (usually I use session.use_only_cookies=1 to avoid that).
They will have different SID if they have different cookie domain or cookies are not working at all and PHP is configured to use only cookies for session ID (session.use_only_cookies=1).
Cookies domain is explained here
Only hosts within the specified domain can set a cookie for a domain and domains must have at least two (2) or three (3) periods in them to prevent domains of the form: ".com", ".edu", and "va.us". Any domain that fails within one of the seven special top level domains listed below only require two periods. Any other domain requires at least three. The seven special top level domains are: "COM", "EDU", "NET", "ORG", "GOV", "MIL", and "INT".
The default value of domain is the host name of the server which generated the cookie response.
So set a common domain for your hosts and they will share cookies, thus PHP SID :)

Categories