tor-browser

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

test_cookies_chips_purge_crash.js (5260B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 add_setup(function test_setup() {
      5  Services.prefs.setIntPref(
      6    "network.cookie.cookieBehavior",
      7    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
      8  );
      9  Services.prefs.setBoolPref(
     10    "network.cookieJarSettings.unblocked_for_testing",
     11    true
     12  );
     13  Services.prefs.setBoolPref(
     14    "network.cookie.cookieBehavior.optInPartitioning",
     15    true
     16  );
     17  Services.prefs.setBoolPref("network.cookie.CHIPS.enabled", true);
     18  Services.prefs.setBoolPref(
     19    "network.cookie.chips.partitionLimitEnabled",
     20    true
     21  );
     22  Services.prefs.setBoolPref(
     23    "network.cookie.chips.partitionLimitDryRun",
     24    false
     25  );
     26  Services.prefs.setIntPref(
     27    "network.cookie.chips.partitionLimitByteCapacity",
     28    24
     29  );
     30 });
     31 
     32 registerCleanupFunction(() => {
     33  Services.prefs.clearUserPref("network.cookie.cookieBehavior");
     34  Services.prefs.clearUserPref(
     35    "network.cookie.cookieBehavior.optInPartitioning"
     36  );
     37  Services.prefs.clearUserPref(
     38    "network.cookieJarSettings.unblocked_for_testing"
     39  );
     40  Services.prefs.clearUserPref("network.cookie.CHIPS.enabled");
     41  Services.prefs.clearUserPref("network.cookie.chips.partitionLimitEnabled");
     42  Services.prefs.clearUserPref("network.cookie.chips.partitionLimitDryRun");
     43  Services.prefs.clearUserPref(
     44    "network.cookie.chips.partitionLimitByteCapacity"
     45  );
     46  Services.cookies.removeAll();
     47 });
     48 
     49 function addChipsCookie(
     50  name,
     51  value,
     52  host,
     53  expiry,
     54  lastAccessed,
     55  creationTime,
     56  db
     57 ) {
     58  let cookie = new Cookie(
     59    name,
     60    value,
     61    host,
     62    "/", // path
     63    expiry,
     64    lastAccessed,
     65    creationTime,
     66    false, // session
     67    true, // secure
     68    false, // http-only
     69    false, // in browser element
     70    { partitionKey: "(https,example.com)" },
     71    Ci.nsICookie.SAMESITE_UNSET,
     72    Ci.nsICookie.SCHEME_UNSET,
     73    true // isPartitioned
     74  );
     75  db.insertCookie(cookie);
     76 }
     77 
     78 add_task(async function test_purge_crash() {
     79  let profile = do_get_profile();
     80  let dbFile = do_get_cookie_file(profile);
     81  Assert.ok(!dbFile.exists());
     82 
     83  let schemaDb = new CookieDatabaseConnection(dbFile, 15);
     84  let now = Date.now() * 1000; // date in microseconds
     85  let past = Math.round(now / 1e3 - 1000);
     86  let future = Math.round(now / 1e3 + 1000) + 20000;
     87  let host = "example.com";
     88 
     89  // add three cookies such that their order in the CookieEntry list is NOT
     90  // sorted by age
     91  // we set up a few cookies to get close to the chips limit, without going over
     92  // if we front-load the list with enough recently used cookies
     93  // we can trigger a crash in the CHIPS purging (before our fix in Bug 1971595)
     94  addChipsCookie("c4", "4", host, future, past + 4000, past, schemaDb);
     95  addChipsCookie("c5", "5", host, future, past + 4000, past, schemaDb);
     96  addChipsCookie("c6", "6", host, future, past + 4000, past, schemaDb);
     97  addChipsCookie("c7", "7", host, future, past + 4000, past, schemaDb);
     98  addChipsCookie("c8", "8", host, future, past + 4000, past, schemaDb);
     99  addChipsCookie("c1", "1", host, future, past, past, schemaDb);
    100  addChipsCookie("c2", "2", host, future, past + 3000, past, schemaDb);
    101  addChipsCookie("c3", "3", host, future, past + 2000, past, schemaDb);
    102 
    103  // check that the cookies were added to the db
    104  Assert.equal(do_count_cookies_in_db(schemaDb.db), 8); // total
    105  Assert.equal(
    106    do_count_cookies_in_db(schemaDb.db, "example.com"), // per host+OA
    107    8
    108  );
    109 
    110  const PATH_EMPTY = "/";
    111  const FIRST_PARTY = "example.com";
    112  const URL_DOCUMENT_FIRSTPARTY = "https://" + FIRST_PARTY + PATH_EMPTY;
    113 
    114  function createPartitionKey(url) {
    115    let uri = NetUtil.newURI(url);
    116    return `(${uri.scheme},${uri.host})`;
    117  }
    118  function createOriginAttributes(partitionKey) {
    119    return JSON.stringify({
    120      firstPartyDomain: "",
    121      geckoViewSessionContextId: "",
    122      inIsolatedMozBrowser: false,
    123      partitionKey,
    124      privateBrowsingId: 0,
    125      userContextId: 0,
    126    });
    127  }
    128  const partitionedOAs = createOriginAttributes(
    129    createPartitionKey(URL_DOCUMENT_FIRSTPARTY)
    130  );
    131 
    132  // validate the db is as expected
    133  // startup the cookie service and check the cookie count
    134  // this shouldn't update the lastAccessed values (which determines cookie age)
    135  let partitioned = Services.cookies.getCookiesWithOriginAttributes(
    136    partitionedOAs,
    137    FIRST_PARTY
    138  );
    139  // a printed list at this point is expected: c4, c5, ..., c8, c1, ...
    140  Assert.equal(partitioned.length, 8);
    141 
    142  // add a CHIPS cookie - triggers a CHIPS purge
    143  // use enough Bytes to trigger the purging of many cookies added before
    144  // this is where the crash occurs
    145  const cv = Services.cookies.add(
    146    host,
    147    "/", // path
    148    "cxxxxx", // name
    149    "yyyyyy", // value
    150    true, // secure
    151    false, // http-only
    152    true, // isSession
    153    future,
    154    { partitionKey: "(https,example.com)" },
    155    Ci.nsICookie.SAMESITE_UNSET, // SameSite
    156    Ci.nsICookie.SCHEME_HTTPS,
    157    true // partitioned
    158  );
    159  Assert.equal(cv.result, Ci.nsICookieValidation.eOK, "Valid cookie");
    160 
    161  // check post-purge cookie count
    162  let postPurgeCookies = Services.cookies.getCookiesWithOriginAttributes(
    163    partitionedOAs,
    164    FIRST_PARTY
    165  );
    166  Assert.equal(postPurgeCookies.length, 5);
    167  schemaDb.close();
    168 });