tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_cookie.js (9596B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 const { cookie } = ChromeUtils.importESModule(
      6  "chrome://remote/content/marionette/cookie.sys.mjs"
      7 );
      8 
      9 cookie.manager = {
     10  cookies: [],
     11 
     12  add(
     13    domain,
     14    path,
     15    name,
     16    value,
     17    secure,
     18    httpOnly,
     19    session,
     20    expiry,
     21    originAttributes,
     22    sameSite
     23  ) {
     24    if (name === "fail") {
     25      throw new Error("An error occurred while adding cookie");
     26    }
     27    let newCookie = {
     28      host: domain,
     29      path,
     30      name,
     31      value,
     32      isSecure: secure,
     33      isHttpOnly: httpOnly,
     34      isSession: session,
     35      expiry,
     36      originAttributes,
     37      sameSite,
     38    };
     39    cookie.manager.cookies.push(newCookie);
     40 
     41    return {
     42      result: Ci.nsICookieValidation.eOK,
     43    };
     44  },
     45 
     46  remove(host, name, path) {
     47    for (let i = 0; i < this.cookies.length; ++i) {
     48      let candidate = this.cookies[i];
     49      if (
     50        candidate.host === host &&
     51        candidate.name === name &&
     52        candidate.path === path
     53      ) {
     54        return this.cookies.splice(i, 1);
     55      }
     56    }
     57    return false;
     58  },
     59 
     60  getCookiesFromHost(host) {
     61    let hostCookies = this.cookies.filter(
     62      c => c.host === host || c.host === "." + host
     63    );
     64 
     65    return hostCookies;
     66  },
     67 };
     68 
     69 add_task(function test_fromJSON() {
     70  // object
     71  for (let invalidType of ["foo", 42, true, [], null, undefined]) {
     72    Assert.throws(
     73      () => cookie.fromJSON(invalidType),
     74      /Expected "cookie" to be an object/
     75    );
     76  }
     77 
     78  // name and value
     79  for (let invalidType of [42, true, [], {}, null, undefined]) {
     80    Assert.throws(
     81      () => cookie.fromJSON({ name: invalidType }),
     82      /Expected cookie "name" to be a string/
     83    );
     84    Assert.throws(
     85      () => cookie.fromJSON({ name: "foo", value: invalidType }),
     86      /Expected cookie "value" to be a string/
     87    );
     88  }
     89 
     90  // domain
     91  for (let invalidType of [42, true, [], {}, null]) {
     92    let domainTest = {
     93      name: "foo",
     94      value: "bar",
     95      domain: invalidType,
     96    };
     97    Assert.throws(
     98      () => cookie.fromJSON(domainTest),
     99      /Expected cookie "domain" to be a string/
    100    );
    101  }
    102  let domainTest = {
    103    name: "foo",
    104    value: "bar",
    105    domain: "domain",
    106  };
    107  let parsedCookie = cookie.fromJSON(domainTest);
    108  equal(parsedCookie.domain, "domain");
    109 
    110  // path
    111  for (let invalidType of [42, true, [], {}, null]) {
    112    let pathTest = {
    113      name: "foo",
    114      value: "bar",
    115      path: invalidType,
    116    };
    117    Assert.throws(
    118      () => cookie.fromJSON(pathTest),
    119      /Expected cookie "path" to be a string/
    120    );
    121  }
    122 
    123  // secure
    124  for (let invalidType of ["foo", 42, [], {}, null]) {
    125    let secureTest = {
    126      name: "foo",
    127      value: "bar",
    128      secure: invalidType,
    129    };
    130    Assert.throws(
    131      () => cookie.fromJSON(secureTest),
    132      /Expected cookie "secure" to be a boolean/
    133    );
    134  }
    135 
    136  // httpOnly
    137  for (let invalidType of ["foo", 42, [], {}, null]) {
    138    let httpOnlyTest = {
    139      name: "foo",
    140      value: "bar",
    141      httpOnly: invalidType,
    142    };
    143    Assert.throws(
    144      () => cookie.fromJSON(httpOnlyTest),
    145      /Expected cookie "httpOnly" to be a boolean/
    146    );
    147  }
    148 
    149  // expiry
    150  for (let invalidType of [
    151    -1,
    152    Number.MAX_SAFE_INTEGER + 1,
    153    "foo",
    154    true,
    155    [],
    156    {},
    157    null,
    158  ]) {
    159    let expiryTest = {
    160      name: "foo",
    161      value: "bar",
    162      expiry: invalidType,
    163    };
    164    Assert.throws(
    165      () => cookie.fromJSON(expiryTest),
    166      /Expected cookie "expiry" to be a positive integer/
    167    );
    168  }
    169 
    170  // sameSite
    171  for (let invalidType of ["foo", 42, [], {}, null]) {
    172    const sameSiteTest = {
    173      name: "foo",
    174      value: "bar",
    175      sameSite: invalidType,
    176    };
    177    Assert.throws(
    178      () => cookie.fromJSON(sameSiteTest),
    179      /Expected cookie "sameSite" to be one of None,Lax,Strict/
    180    );
    181  }
    182 
    183  // bare requirements
    184  let bare = cookie.fromJSON({ name: "name", value: "value" });
    185  equal("name", bare.name);
    186  equal("value", bare.value);
    187  for (let missing of [
    188    "path",
    189    "secure",
    190    "httpOnly",
    191    "session",
    192    "expiry",
    193    "sameSite",
    194  ]) {
    195    ok(!bare.hasOwnProperty(missing));
    196  }
    197 
    198  // everything
    199  let full = cookie.fromJSON({
    200    name: "name",
    201    value: "value",
    202    domain: ".domain",
    203    path: "path",
    204    secure: true,
    205    httpOnly: true,
    206    expiry: 42,
    207    sameSite: "Lax",
    208  });
    209  equal("name", full.name);
    210  equal("value", full.value);
    211  equal(".domain", full.domain);
    212  equal("path", full.path);
    213  equal(true, full.secure);
    214  equal(true, full.httpOnly);
    215  equal(42, full.expiry);
    216  equal("Lax", full.sameSite);
    217 });
    218 
    219 add_task(function test_add() {
    220  cookie.manager.cookies = [];
    221 
    222  for (let invalidType of [42, true, [], {}, null, undefined]) {
    223    Assert.throws(
    224      () => cookie.add({ name: invalidType }),
    225      /Expected cookie "name" to be a string/
    226    );
    227    Assert.throws(
    228      () => cookie.add({ name: "name", value: invalidType }),
    229      /Expected cookie "value" to be a string/
    230    );
    231    Assert.throws(
    232      () => cookie.add({ name: "name", value: "value", domain: invalidType }),
    233      /Expected cookie "domain" to be a string/
    234    );
    235  }
    236 
    237  cookie.add({
    238    name: "name",
    239    value: "value",
    240    domain: "domain",
    241  });
    242  equal(1, cookie.manager.cookies.length);
    243  equal("name", cookie.manager.cookies[0].name);
    244  equal("value", cookie.manager.cookies[0].value);
    245  equal(".domain", cookie.manager.cookies[0].host);
    246  equal("/", cookie.manager.cookies[0].path);
    247  Assert.greater(
    248    cookie.manager.cookies[0].expiry,
    249    new Date(Date.now()).getTime() / 1000
    250  );
    251 
    252  cookie.add({
    253    name: "name2",
    254    value: "value2",
    255    domain: "domain2",
    256  });
    257  equal(2, cookie.manager.cookies.length);
    258 
    259  Assert.throws(() => {
    260    let biscuit = { name: "name3", value: "value3", domain: "domain3" };
    261    cookie.add(biscuit, { restrictToHost: "other domain" });
    262  }, /Cookies may only be set for the current domain/);
    263 
    264  cookie.add({
    265    name: "name4",
    266    value: "value4",
    267    domain: "my.domain:1234",
    268  });
    269  equal(".my.domain", cookie.manager.cookies[2].host);
    270 
    271  cookie.add({
    272    name: "name5",
    273    value: "value5",
    274    domain: "domain5",
    275    path: "/foo/bar",
    276  });
    277  equal("/foo/bar", cookie.manager.cookies[3].path);
    278 
    279  cookie.add({
    280    name: "name6",
    281    value: "value",
    282    domain: ".domain",
    283  });
    284  equal(".domain", cookie.manager.cookies[4].host);
    285 
    286  const aDayInSec = 60 * 60 * 24;
    287  const nowInSec = Math.round(Date.now() / 1000);
    288  const tenDaysInTheFutureInSec = nowInSec + aDayInSec * 10;
    289 
    290  cookie.add({
    291    name: "name6",
    292    value: "value",
    293    domain: ".domain",
    294    expiry: tenDaysInTheFutureInSec,
    295  });
    296  equal(tenDaysInTheFutureInSec * 1000, cookie.manager.cookies[5].expiry);
    297 
    298  const two1000DaysInTheFutureInSec = nowInSec + aDayInSec * 2000;
    299  cookie.add({
    300    name: "name6",
    301    value: "value",
    302    domain: ".domain",
    303    expiry: two1000DaysInTheFutureInSec,
    304  });
    305 
    306  const maxageCap = Services.prefs.getIntPref("network.cookie.maxageCap");
    307  if (maxageCap) {
    308    // To avoid timing race condition, let's compare the expiry value with maxageCap +/- a few seconds.
    309    const maxageCapMin = nowInSec + maxageCap - 3; /* secs */
    310    const maxageCapMax = nowInSec + maxageCap + 3; /* secs */
    311 
    312    // Max allowed value: 400 days.
    313    Assert.greater(maxageCapMax * 1000, cookie.manager.cookies[6].expiry);
    314    Assert.greater(cookie.manager.cookies[6].expiry, maxageCapMin * 1000);
    315  }
    316 
    317  const sameSiteMap = new Map([
    318    ["None", Ci.nsICookie.SAMESITE_NONE],
    319    ["Lax", Ci.nsICookie.SAMESITE_LAX],
    320    ["Strict", Ci.nsICookie.SAMESITE_STRICT],
    321  ]);
    322 
    323  Array.from(sameSiteMap.keys()).forEach((entry, index) => {
    324    cookie.add({
    325      name: "name" + index,
    326      value: "value",
    327      domain: ".domain",
    328      sameSite: entry,
    329    });
    330    equal(sameSiteMap.get(entry), cookie.manager.cookies[7 + index].sameSite);
    331  });
    332 
    333  Assert.throws(() => {
    334    cookie.add({ name: "fail", value: "value6", domain: "domain6" });
    335  }, /UnableToSetCookieError/);
    336 });
    337 
    338 add_task(function test_remove() {
    339  cookie.manager.cookies = [];
    340 
    341  let crumble = {
    342    name: "test_remove",
    343    value: "value",
    344    domain: "domain",
    345    path: "/custom/path",
    346  };
    347 
    348  equal(0, cookie.manager.cookies.length);
    349  cookie.add(crumble);
    350  equal(1, cookie.manager.cookies.length);
    351 
    352  cookie.remove(crumble);
    353  equal(0, cookie.manager.cookies.length);
    354  equal(undefined, cookie.manager.cookies[0]);
    355 });
    356 
    357 add_task(function test_iter() {
    358  cookie.manager.cookies = [];
    359  let tomorrow = new Date();
    360  tomorrow.setHours(tomorrow.getHours() + 24);
    361 
    362  cookie.add({
    363    expiry: tomorrow,
    364    name: "0",
    365    value: "",
    366    domain: "foo.example.com",
    367  });
    368  cookie.add({
    369    expiry: tomorrow,
    370    name: "1",
    371    value: "",
    372    domain: "bar.example.com",
    373  });
    374 
    375  let fooCookies = [...cookie.iter("foo.example.com")];
    376  equal(1, fooCookies.length);
    377  equal(".foo.example.com", fooCookies[0].domain);
    378  equal(true, fooCookies[0].hasOwnProperty("expiry"));
    379 
    380  cookie.add({
    381    name: "aSessionCookie",
    382    value: "",
    383    domain: "session.com",
    384  });
    385 
    386  let sessionCookies = [...cookie.iter("session.com")];
    387  equal(1, sessionCookies.length);
    388  equal("aSessionCookie", sessionCookies[0].name);
    389  equal(false, sessionCookies[0].hasOwnProperty("expiry"));
    390 
    391  cookie.add({
    392    name: "2",
    393    value: "",
    394    domain: "samesite.example.com",
    395    sameSite: "Lax",
    396  });
    397 
    398  let sameSiteCookies = [...cookie.iter("samesite.example.com")];
    399  equal(1, sameSiteCookies.length);
    400  equal("Lax", sameSiteCookies[0].sameSite);
    401 });