简体   繁体   中英

Cookie collision: is it possible to distinguish between parent domain and subdomain cookies in Django and Javascript?

I have built a bunch of Django websites at a single domain:

  • example.com
  • site1.example.com
  • site2.example.com
  • site3.example.com

They are supposed to be completely independent — used by different people for different purposes.

However cookies set by example.com are given priority by Django, and values set by site1.example.com , site2.example.com etc. are ignored if the parent domain has set a cookie with the same name.


How it works:

When the first page is loaded, it sets a cookie so the server knows to send a computer page or a mobile page with the next request.

The Django program builds the correct version based on the cookie value.

When site1.example.com loads, it sets a cookie asking for the mobile version. But then the Django program sees the value set by example.com and ignores the correct cookie .

So, I need a way to do one of the following:

  1. prevent site1.example.com from reading the cookie of example.com
  2. differentiate in Django the domain associated with the cookie so I can tell that the value is wrong
  3. find a way to set a parent domain cookie in Javascript that makes it inaccessible to subdomains (I'm not using www)

If I can't find an elegant solution, I will likely end up changing the cookie name to vary with the domain name.

I know that I could use the session framework , but apart from this particular issue, everything works great. I would really like to avoid modifying my existing system, though obviously I will if I have to.

[update] Here is the cookie-setting function:

function setCookie(cname, cvalue, exdays) {

  var domain = window.location.hostname;


  if (exdays > 7) exdays = 7; // max in Safari

  var d = new Date();
  d.setTime(d.getTime() + (exdays*24*60*60*1000));

  var name = cname + '=' + cvalue + '; ';
  var expy = 'expires=' + d.toUTCString(); + '; ';
  var domn = '; domain=' + domain + '; ';
  var path = 'path=/; ';
  var secu = 'samesite=lax; secure;';

  var complete = name + expy + domn + path + secu;
  document.cookie = complete;
}

Since you say the websites are supposed to be completely independent the 3rd solution you propose seems most sensible. You should not be setting cookies in such a way that they are accessible by subdomains. Currently you are specifying the domain in the cookie, you should be skipping the domain which would mean the cookie would only be sent for the current domain (At least in modern browsers, IE does not follow this specification). If a domain is specified in the cookie it means that the cookie would also be used for the subdomains.

As mentioned in RFC 6265 - section 4.1.2.3 :

If the server omits the Domain attribute, the user agent will return the cookie only to the origin server.

Hence your cookie setting function should be like the following:

function setCookie(cname, cvalue, exdays) {
  // Domain should not be set unless cookie needs to be accessed by subdomains
  // var domain = window.location.hostname;


  if (exdays > 7) exdays = 7; // max in Safari

  var d = new Date();
  d.setTime(d.getTime() + (exdays*24*60*60*1000));

  var name = cname + '=' + cvalue + '; ';
  var expy = 'expires=' + d.toUTCString(); + '; ';
  // Domain should not be set unless cookie needs to be accessed by subdomains
  // var domn = '; domain=' + domain + '; ';
  var path = 'path=/; ';
  var secu = 'samesite=lax; secure;';

  var complete = name + expy + path + secu;
  document.cookie = complete;
}

As a temporary fix, I added some code to my setCookie function :

  var domain = window.location.hostname;
  deleteParentCookieIfNecessary(name, domain);

deleteParentCookieIfNecessary contains:

function deleteParentCookieIfNecessary(name, domain){
  var parts = domain.split('.');
  if (parts.length > 2){ // on subdomain
    var domain = parts.slice(-2).join('.');
    document.cookie = cname + '=;domain=.' + domain + ';path=/;max-age=0';
  }
}

The result is that when the cookie is set , if the url is a subdomain then the parent-domain's cookie of the same name will be automatically deleted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM