tor-browser

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

test_invalid_cookie_fix.js (10254B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 class CookieValidatedObserver {
      7  #promise;
      8 
      9  static waitForCookieValidation() {
     10    return new Promise(resolve => {
     11      new CookieValidatedObserver(resolve);
     12    });
     13  }
     14 
     15  constructor(promise) {
     16    this.#promise = promise;
     17 
     18    this.obs = Services.obs;
     19    this.obs.addObserver(this, "cookies-validated");
     20  }
     21 
     22  observe(subject, topic) {
     23    if (topic == "cookies-validated") {
     24      if (this.obs) {
     25        this.obs.removeObserver(this, "cookies-validated");
     26      }
     27 
     28      this.#promise();
     29    }
     30  }
     31 }
     32 
     33 add_task(async function test_invalid_cookie_fix() {
     34  let promise = CookieValidatedObserver.waitForCookieValidation();
     35 
     36  // Set up a profile.
     37  let profile = do_get_profile();
     38 
     39  // Start the cookieservice, to force creation of a database.
     40  Services.cookies.sessionCookies;
     41 
     42  // Each cookie-db opening will trigger a validation.
     43  await promise;
     44 
     45  // Close the profile.
     46  await promise_close_profile();
     47 
     48  // Remove the cookie file in order to create another database file.
     49  do_get_cookie_file(profile).remove(false);
     50 
     51  // Create a schema 16 database.
     52  let schema16db = new CookieDatabaseConnection(
     53    do_get_cookie_file(profile),
     54    17
     55  );
     56 
     57  const nowInMSec = Date.now();
     58  const farFarInThePastInMSec = nowInMSec - 60 * 60 * 24 * 1000 * 1000;
     59  const farFarInTheFutureInMSec = nowInMSec + 60 * 60 * 24 * 1000 * 1000;
     60  const nearFutureInMSec = nowInMSec + 60 * 60 * 24 * 1000;
     61  const nowInUSec = nowInMSec * 1000;
     62  const farFarInThePastInUSec = farFarInThePastInMSec * 1000;
     63 
     64  // CookieValidation.result => eRejectedNoneRequiresSecure
     65  schema16db.insertCookie(
     66    new Cookie(
     67      "test1",
     68      "Some data",
     69      "foo.com",
     70      "/",
     71      nearFutureInMSec,
     72      nowInUSec,
     73      nowInUSec,
     74      false,
     75      false,
     76      false,
     77      false,
     78      {},
     79      Ci.nsICookie.SAMESITE_NONE,
     80      Ci.nsICookie.SCHEME_UNSET,
     81      nowInUSec
     82    )
     83  );
     84 
     85  // CookieValidation.result => eOK
     86  schema16db.insertCookie(
     87    new Cookie(
     88      "test2",
     89      "Some data",
     90      "foo.com",
     91      "/",
     92      nearFutureInMSec,
     93      nowInUSec,
     94      nowInUSec,
     95      false,
     96      false,
     97      false,
     98      false,
     99      {},
    100      Ci.nsICookie.SAMESITE_LAX,
    101      Ci.nsICookie.SCHEME_UNSET,
    102      nowInUSec
    103    )
    104  );
    105 
    106  // CookieValidation.result => eOK
    107  schema16db.insertCookie(
    108    new Cookie(
    109      "test3",
    110      "Some data",
    111      "foo.com",
    112      "/",
    113      nearFutureInMSec,
    114      nowInUSec,
    115      nowInUSec,
    116      false,
    117      false,
    118      false,
    119      false,
    120      {},
    121      Ci.nsICookie.SAMESITE_STRICT,
    122      Ci.nsICookie.SCHEME_UNSET,
    123      nowInUSec
    124    )
    125  );
    126 
    127  // CookieValidation.result => eOK
    128  schema16db.insertCookie(
    129    new Cookie(
    130      "test4",
    131      "Some data",
    132      "foo.com",
    133      "/",
    134      nearFutureInMSec,
    135      nowInUSec,
    136      nowInUSec,
    137      false,
    138      false,
    139      false,
    140      false,
    141      {},
    142      Ci.nsICookie.SAMESITE_UNSET,
    143      Ci.nsICookie.SCHEME_UNSET,
    144      nowInUSec
    145    )
    146  );
    147 
    148  // CookieValidation.result => eRejectedNoneRequiresSecure
    149  schema16db.insertCookie(
    150    new Cookie(
    151      "test5",
    152      "Some data",
    153      "foo.com",
    154      "/",
    155      nearFutureInMSec,
    156      nowInUSec,
    157      nowInUSec,
    158      false,
    159      true,
    160      false,
    161      false,
    162      {},
    163      Ci.nsICookie.SAMESITE_NONE,
    164      Ci.nsICookie.SCHEME_UNSET,
    165      nowInUSec
    166    )
    167  );
    168 
    169  // CookieValidation.result => eRejectedAttributeExpiryOversize
    170  schema16db.insertCookie(
    171    new Cookie(
    172      "test6",
    173      "Some data",
    174      "foo.com",
    175      "/",
    176      farFarInTheFutureInMSec,
    177      nowInUSec,
    178      nowInUSec,
    179      false,
    180      false,
    181      false,
    182      false,
    183      {},
    184      Ci.nsICookie.SAMESITE_UNSET,
    185      Ci.nsICookie.SCHEME_UNSET,
    186      nowInUSec
    187    )
    188  );
    189 
    190  // CookieValidation.result => eRejectedEmptyNameAndValue
    191  schema16db.insertCookie(
    192    new Cookie(
    193      "",
    194      "",
    195      "foo.com",
    196      "/",
    197      nearFutureInMSec,
    198      nowInUSec,
    199      nowInUSec,
    200      false,
    201      false,
    202      false,
    203      false,
    204      {},
    205      Ci.nsICookie.SAMESITE_UNSET,
    206      Ci.nsICookie.SCHEME_UNSET,
    207      nowInUSec
    208    )
    209  );
    210 
    211  // CookieValidation.result => eRejectedInvalidCharName
    212  schema16db.insertCookie(
    213    new Cookie(
    214      " test8",
    215      "",
    216      "foo.com",
    217      "/",
    218      nearFutureInMSec,
    219      nowInUSec,
    220      nowInUSec,
    221      false,
    222      false,
    223      false,
    224      false,
    225      {},
    226      Ci.nsICookie.SAMESITE_UNSET,
    227      Ci.nsICookie.SCHEME_UNSET,
    228      nowInUSec
    229    )
    230  );
    231 
    232  // CookieValidation.result => eRejectedInvalidCharValue
    233  schema16db.insertCookie(
    234    new Cookie(
    235      "test9",
    236      " test9",
    237      "foo.com",
    238      "/",
    239      nearFutureInMSec,
    240      nowInUSec,
    241      nowInUSec,
    242      false,
    243      false,
    244      false,
    245      false,
    246      {},
    247      Ci.nsICookie.SAMESITE_UNSET,
    248      Ci.nsICookie.SCHEME_UNSET,
    249      nowInUSec
    250    )
    251  );
    252 
    253  // CookieValidation.result => eOK
    254  schema16db.insertCookie(
    255    new Cookie(
    256      "testA",
    257      "Some data",
    258      "foo.com",
    259      "/",
    260      nearFutureInMSec,
    261      nowInUSec,
    262      farFarInThePastInUSec,
    263      false,
    264      false,
    265      false,
    266      false,
    267      {},
    268      Ci.nsICookie.SAMESITE_UNSET,
    269      Ci.nsICookie.SCHEME_UNSET,
    270      nowInUSec
    271    )
    272  );
    273 
    274  schema16db.close();
    275  schema16db = null;
    276 
    277  // Check if we have the right entries
    278  {
    279    const dbConnection = Services.storage.openDatabase(
    280      do_get_cookie_file(profile)
    281    );
    282    const stmt = dbConnection.createStatement(
    283      "SELECT name, sameSite, isSecure, creationTime, expiry FROM moz_cookies ORDER BY name"
    284    );
    285 
    286    const results = [];
    287    while (stmt.executeStep()) {
    288      results.push({
    289        name: stmt.getString(0),
    290        sameSite: stmt.getInt32(1),
    291        isSecure: stmt.getInt32(2),
    292        creationTime: stmt.getInt64(3),
    293        expiry: stmt.getInt64(4),
    294      });
    295    }
    296 
    297    Assert.deepEqual(results, [
    298      {
    299        name: "",
    300        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    301        isSecure: 0,
    302        creationTime: nowInUSec,
    303        expiry: nearFutureInMSec,
    304      },
    305      {
    306        name: " test8",
    307        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    308        isSecure: 0,
    309        creationTime: nowInUSec,
    310        expiry: nearFutureInMSec,
    311      },
    312      {
    313        name: "test1",
    314        sameSite: Ci.nsICookie.SAMESITE_NONE,
    315        isSecure: 0,
    316        creationTime: nowInUSec,
    317        expiry: nearFutureInMSec,
    318      },
    319      {
    320        name: "test2",
    321        sameSite: Ci.nsICookie.SAMESITE_LAX,
    322        isSecure: 0,
    323        creationTime: nowInUSec,
    324        expiry: nearFutureInMSec,
    325      },
    326      {
    327        name: "test3",
    328        sameSite: Ci.nsICookie.SAMESITE_STRICT,
    329        isSecure: 0,
    330        creationTime: nowInUSec,
    331        expiry: nearFutureInMSec,
    332      },
    333      {
    334        name: "test4",
    335        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    336        isSecure: 0,
    337        creationTime: nowInUSec,
    338        expiry: nearFutureInMSec,
    339      },
    340      {
    341        name: "test5",
    342        sameSite: Ci.nsICookie.SAMESITE_NONE,
    343        isSecure: 1,
    344        creationTime: nowInUSec,
    345        expiry: nearFutureInMSec,
    346      },
    347      {
    348        name: "test6",
    349        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    350        isSecure: 0,
    351        creationTime: nowInUSec,
    352        expiry: farFarInTheFutureInMSec,
    353      },
    354      {
    355        name: "test9",
    356        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    357        isSecure: 0,
    358        creationTime: nowInUSec,
    359        expiry: nearFutureInMSec,
    360      },
    361      {
    362        name: "testA",
    363        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    364        isSecure: 0,
    365        creationTime: farFarInThePastInUSec,
    366        expiry: nearFutureInMSec,
    367      },
    368    ]);
    369 
    370    stmt.finalize();
    371    dbConnection.close();
    372  }
    373 
    374  promise = CookieValidatedObserver.waitForCookieValidation();
    375 
    376  // Reload profile.
    377  await promise_load_profile();
    378 
    379  await promise;
    380 
    381  // Assert inserted cookies are in the db and correctly handled by services.
    382  Assert.equal(Services.cookies.countCookiesFromHost("foo.com"), 7);
    383 
    384  // Close the profile.
    385  await promise_close_profile();
    386 
    387  // Check if the sameSite issues were fixed
    388  {
    389    const dbConnection = Services.storage.openDatabase(
    390      do_get_cookie_file(profile)
    391    );
    392    const stmt = dbConnection.createStatement(
    393      "SELECT name, sameSite, isSecure, creationTime, expiry FROM moz_cookies ORDER BY name"
    394    );
    395 
    396    const results = [];
    397    while (stmt.executeStep()) {
    398      results.push({
    399        name: stmt.getString(0),
    400        sameSite: stmt.getInt32(1),
    401        isSecure: stmt.getInt32(2),
    402        creationTime: stmt.getInt64(3),
    403        expiry: stmt.getInt64(4),
    404      });
    405    }
    406 
    407    Assert.deepEqual(results, [
    408      {
    409        name: "test1",
    410        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    411        isSecure: 0,
    412        creationTime: nowInUSec,
    413        expiry: nearFutureInMSec,
    414      },
    415      {
    416        name: "test2",
    417        sameSite: Ci.nsICookie.SAMESITE_LAX,
    418        isSecure: 0,
    419        creationTime: nowInUSec,
    420        expiry: nearFutureInMSec,
    421      },
    422      {
    423        name: "test3",
    424        sameSite: Ci.nsICookie.SAMESITE_STRICT,
    425        isSecure: 0,
    426        creationTime: nowInUSec,
    427        expiry: nearFutureInMSec,
    428      },
    429      {
    430        name: "test4",
    431        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    432        isSecure: 0,
    433        creationTime: nowInUSec,
    434        expiry: nearFutureInMSec,
    435      },
    436      {
    437        name: "test5",
    438        sameSite: Ci.nsICookie.SAMESITE_NONE,
    439        isSecure: 1,
    440        creationTime: nowInUSec,
    441        expiry: nearFutureInMSec,
    442      },
    443      {
    444        name: "test6",
    445        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    446        isSecure: 0,
    447        creationTime: nowInUSec,
    448        expiry: results.find(a => a.name === "test6").expiry,
    449      },
    450      {
    451        name: "testA",
    452        sameSite: Ci.nsICookie.SAMESITE_UNSET,
    453        isSecure: 0,
    454        creationTime: farFarInThePastInUSec,
    455        expiry: nearFutureInMSec,
    456      },
    457    ]);
    458 
    459    for (const r of results) {
    460      Assert.less(r.expiry, farFarInTheFutureInMSec);
    461    }
    462 
    463    stmt.finalize();
    464    dbConnection.close();
    465  }
    466 
    467  // Cleanup
    468  await promise_load_profile();
    469  Services.cookies.removeAll();
    470  do_close_profile();
    471 });