Automatically set cookie to highest possible cookie domain via Javascript - javascript

Is there a good programmatic way to automatically set a cookie on the highest possible domain?
For example:
sub1.sub2.example.com -> example.com
sub1.sub2.example.co.uk -> example.co.uk
When setting a cookie using document.cookie = ... there is no error when trying to set a cookie for a domain that is "out of scope".
I guess I could iterate through each "level" and try to set a cookie there, so:
sub1.sub2.example.com
sub2.example.com
example.com
com
But I would only want the cookie to be set on example.com and not any of the subdomains.
If there was some kind of error, I could start from the bottom and stop when no exception occurs. But as there is no error, that does not work.
Or I guess I could compare document.cookie after each level (also starting from the bottom) and check if my desired value is set. But that also seems quite bad.
Are there any other good solutions?

Related

JavaScript Cookie Scope change leaves 2 Cookies with same name but which one will be read?

I recently had cookies set to a specific sub-domain (i.e. "cookie1" set to sub1.mysite.com). I then changed the code to write the same name cookie to the domain (i.e. "cookie1 set to .mysite.com). Now if I hit a page without clearing cookies, I see the two cookies with the same name but scoped differently. So my question is when on sub1.mysite.com, which cookie will be read due to two cookies existing with same name and both in scope?
Thanks,
MJ
The cookie with the most specific matching scope will be used. This allows a subdomain to override a domain-wide default cookie.

Is there a way to retrieve a cookie by it's domain in JavaScript

It doesn't seem that JS provide any ability off the bat to grab the value of a cookie based on the domain, but does anyone have a suggestion as to how this can be done?
For example:
There may be two cookies with the same name, but one is set globally across all pages (.example.com) and the other is set on a certain page (sub.example.com).
document.cookie
will only retrieve a string of all the cookie key:value pairs, with no association to the appropriate domain. ex:
"this_cookie=abc; that_cookie=xyz; this_cookie=123"
I would like to grab the cookie which is instantiated on the subdomain (this_cookie #2)
document.cookie does not expose the domain information as you can see for yourself.
Just an idea: Maybe you can store document.cookie temporarily, then override the cookie for the subdomain and compare again with document.cookie to see which has changed.
But to be honest: Can you not put the subdomain into the cookie name or value?
You cannot. or there will be security vulnerabilities.
When you setup the cookie on subdomain, you have to set "globally across all pages (.example.com)" so that you can retrieve it from the main domain.

Cookie is set twice; how to remove the duplicate?

So I have a website that uses a cookie to remember the current layout state across visits. Everything was working great until I added a Facebook 'Like' button to the site which generates links that allow users to share a certain UI state (a little confusing but not really relevant to the problem).
The problem is that when I visit the site via one of these Facebook links a second copy of my layout cookie seems to be created (as in, I see two cookies with the same name and different values). This wouldn't be too terrible except that the value of the duplicate cookie appears to be stuck, coupled with the fact that when the user returns to the site the browser remembers the stuck value instead of the most recently set value (so it's kind of like there's a "good" cookie that I can still work with, and a "bad" one which I cannot, and the browser likes to remember the "bad" cookie instead of the "good" cookie). This breaks my layout tracking/remembering functionality.
So there are two questions here:
How do I stop this from happening/why is this happening in the first place?
How do I fix things for any users that already have a stuck cookie (I know I could just pick a new name for the cookie, but I'd rather do it by finding a way to properly unstick the stuck cookie)?
If I use Chrome's developer console after visiting the page in a stuck state, I can see that document.cookie is (formatting added for readability):
layoutState=[{'id':6,'x':8,'y':1525,'z':4,'url':'undefined'}, {'id':1,'x':625,'y':709,'z':2,'url':'undefined'}, {'id':2,'x':8,'y':37,'z':3,'url':'undefined'}, {'id':3,'x':625,'y':1179,'z':5,'url':'undefined'}, {'id':4,'x':626,'y':37,'z':1,'url':'undefined'}, {'id':5,'x':626,'y':357,'z':1000000,'url':'http://m.xkcd.com/303/'}];
WibiyaNotification1=1;
WibiyaNotification213286=213286;
WibiyaNotification213289=213289; wibiya756904_unique_user=1;
JSESSIONID=DONTHIJACKMEPLEASE;
WibiyaProfile={"toolbar":{"stat":"Max"},"apps":{"openApps":{}},"connectUserNetworks":[null,null,null,null,null,null]};
WibiyaLoads=59;
layoutState=[{'id':6,'x':8,'y':1525,'z':4,'url':'undefined'}, {'id':1,'x':625,'y':709,'z':2,'url':'undefined'}, {'id':2,'x':8,'y':37,'z':3,'url':'undefined'}, {'id':3,'x':625,'y':1179,'z':5,'url':'undefined'}, {'id':4,'x':626,'y':37,'z':1,'url':'undefined'}, {'id':5,'x':626,'y':357,'z':6,'url':'http://m.xkcd.com/303/'}]"
Ignore the Wibiya cookies and the JSESSIONID. The stuck cookie is the first 'layoutState' instance, and the one that I can still manipulate in JavaScript is the second 'layoutState' instance. Here is what I get if I change some things around:
layoutState=[{'id':6,'x':8,'y':1525,'z':4,'url':'undefined'}, {'id':1,'x':625,'y':709,'z':2,'url':'undefined'}, {'id':2,'x':8,'y':37,'z':3,'url':'undefined'}, {'id':3,'x':625,'y':1179,'z':5,'url':'undefined'}, {'id':4,'x':626,'y':37,'z':1,'url':'undefined'}, {'id':5,'x':626,'y':357,'z':1000000,'url':'http://m.xkcd.com/303/'}];
WibiyaNotification1=1;
WibiyaNotification213286=213286;
WibiyaNotification213289=213289;
wibiya756904_unique_user=1;
JSESSIONID=DONTHIJACKMEPLEASE;
WibiyaProfile={"toolbar":{"stat":"Max"},"apps":{"openApps":{}},"connectUserNetworks":[null,null,null,null,null,null]};
WibiyaLoads=59;
layoutState=[{'id':1,'x':8,'y':39,'z':1000000,'url':'undefined'}]
The second 'layoutState' has the correct information that I want the browser to remember. However what the browser actually remembers is the value of the first instance.
I've tried unsetting the cookie entirely, which causes the second instance to disappear, but nothing I do seems to get rid of the first instance. I get the same behavior in all major browsers (Chrome, Firefox, IE), which makes me suspect that I must be doing something fundamentally wrong here, but I'm not sure what it is.
You can view the site itself here. Or click here to access it via a Facebook link (should generate a stuck cookie). Any help is much appreciated.
Update:
So the steps to reliably reproduce the error are as follows:
Visit the site via the Facebook-style link
Make some changes to the layout, and then close the tab.
Visit the site via the normal URL.
Your layout from the initial visit should be correctly remembered, so change some things around and then refresh the page. When the page reloads, your changes will no longer be remembered.
I've also noticed that revisiting the site via the Facebook-style URL is able to clear/reset the stuck cookie. So it's like the browser is keeping a separate cookie for each URL path, or something, and not allowing the root page to access the cookie that was set on the other URL path. I thought I might be able to fix this by explicitly setting path=/ on the cookie, but no dice.
Update 2:
I've found that if I set both the path and the domain of the cookie I get different behavior in all browsers:
Firefox - Works correctly now, hooray! Worked correctly once, then broke, boo!
Chrome - No change
IE - Seems to be keeping separate cookies for each URL, so the Facebook-style URL remembers one state, and the standard URL remembers a different state. Both update correctly and independently of each other. This is kind of funky, but still way better than the stuck/broken state.
Dude(tte), there are inconsistencies, and a bug, in your cookie setter.
1. Make sure path and domain is correctly set
The path and domain should be the same for both clearing the cookie and setting it. See your code here:
document.cookie = c_name + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
and compare it to:
var c_value=escape(value) + "; expires=" + exdate.toUTCString(); + "; path=/spring; domain=aroth.no-ip.org";
you will see that the setter has both of them, but the deleter doesn't. You will bring about chaos.
2. Oh, and that nasty semicolon
That second line of code I quoted above, has a semicolon introduced in the middle of a string concatenation expression. Right after exdate.toUTCString(). Kill it. Kill it…now.
At least on my Google Chrome, I managed to get it run correctly, if I set a breakpoint at json = "[" + json + "]"; and modify setCookie before it is executed.
P/S: It was a bizzare debugging experience, where I managed to set 4 layoutState cookies, by fiddling with path & domain.
This may be too simple, but just in case, are the cookies recorded for two different paths? If the URL is different, you may be setting your cookies for a restricted path, so the system would take them differently.
Here is a solution, the / slash help to do not set duplicate cookie of same name
setcookie('YourCookieName','yes', time() + 400, '/');
check in Chrome console -> Resources if your page gets loaded twice. That would be the reason of double cookie.
There is again the problem left after identifying the problem and taking prevention by correctly setting the cookie.
You also need to delete previous incorrectly set cookies in your or in your client's browser.
So observe the cookie set from developer tools and search for path and subdomain and put those explicitly on your code to delete.
function eraseCookie(c_name) {
document.cookie = c_name + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
}
function eraseCookieWithPathDomain(c_name) {
document.cookie = c_name + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;path=/yourpath/to; domain=sub.domain.com";
//you can remove this function call on your second upload if you are confirm that the previous cookie setter expired
}
You may need to call function eraseCookieWithPathDomain right after eraseCookie or even every time after document load depending in your application.
You can add the following key in the AppSettings in the web config file it solves the issue of duplicate cookie.
<!-- Tell ASPNET to avoid duplicate Set-Cookies on the Response Headers-->
<appSettings>
<add key="aspnet:AvoidDuplicatedSetCookie" value="true" />
</appSettings>
This will help avoiding the duplicate Set-Cookie() in Response Headers.
It seems the issue is not a duplicate cookie (cookies overwrite themselves) but a duplication of the DATA in your cookie.
I think you'll have to modify the script that reads the cookie and clean out the duplicate value if it's detected.

How do I distinguish between duplicate cookies?

I am observing, on both Firefox and IE, that if I have a cookie 'x' on the domain a.b.c.com, and also have a cookie with the same name 'x' on domain a.b.com, then when I look at the value of document.cookie on the a.b.c.com domain, it shows both cookies. I would like to see just the cookie from the a.b.c.com domain, and not the one from the other domain. (I'm assuming this occurs because one domain is the same as the other one, with an additional segment on the hostname.) Is there a way to do this?
I don't have control over the contents of the cookie, and I don't see anything obvious in those contents that distinguishes one domain from the other.
You don't have access to the domain of the cookie in Javascript.
"When [the cookie] attribute is read, all
cookies are returned as a single
string, with each cookie's name-value
pair concatenated into a list of
name-value pairs, each list item being
separated by a ';' (semicolon)."
W3C
When you read a cookie, you only have access to the name/value pairs, and cannot determine any other information about it. If you require things such as when it was set, what domains it was set for, or anything else, you have to store it inside the cookie value.
Since you cannot set the cookies, you need another method to do what you're attempting.

Retrieving cookies

I was wondering how I could retrieve a cookie that has a path specified - something like path=/foo/bar... If I use document.cookie that only retrieves me JSessionId cookie.. which I guess is the only one with path=/.
Are you trying to retrieve the cookie based on the path and not the name? It's possible to have many cookies that match a specified path. Also have a look at jQuery and the Cookie plugin. Setting and retrieving cookies is as easy as:
// get cookie
$.cookie(COOKIE_NAME)
// set cookie
$.cookie(COOKIE_NAME, 'test', { path: '/your/path', expires: 7});
http://plugins.jquery.com/project/cookie
I have figured out how to solve the problem... Just to let anyone reading this, the idea was to test one of the applications for cross site scripting attack (xss), and the cookie contained valuable information that i wanted to retrieve. The problem was that the cookie was on the other path than the web app itself. I had to access the app using /somedomain/project and the cookie had the /somedomain/project/project path set. SO I somehow had to open /somedomain/project/project url to be able to retrieve the cookie I needed. To get to that cookie I have injected an iframe element. inside that iframe element i made an ajax call. it was a dummy call to /somedomain/project/project/ just to get some information in the iframe ant to make sure iframe's document objects get created. that iframe's document object contained the cookie that i needed. After that I have made an XmlHTTPRequest call to a remote service and sent the cookie as a parameter to the remote server.

Categories

Resources