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 });