File: cookie-helper.sub.js

package info (click to toggle)
firefox-esr 91.13.0esr-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 3,375,652 kB
  • sloc: cpp: 5,762,054; javascript: 5,481,714; ansic: 3,121,191; python: 851,492; asm: 331,172; xml: 178,949; java: 155,554; sh: 63,704; makefile: 20,127; perl: 12,825; yacc: 4,583; cs: 3,846; objc: 3,026; lex: 1,720; exp: 762; pascal: 635; php: 436; lisp: 260; awk: 231; ruby: 103; sed: 53; sql: 46; csh: 45
file content (339 lines) | stat: -rw-r--r-- 15,550 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
// Set up exciting global variables for cookie tests.
(_ => {
  var HOST = "{{host}}";
  var INSECURE_PORT = ":{{ports[http][0]}}";
  var SECURE_PORT = ":{{ports[https][0]}}";
  var CROSS_ORIGIN_HOST = "{{hosts[alt][]}}";

  window.INSECURE_ORIGIN = "http://" + HOST + INSECURE_PORT;

  //For secure cookie verification
  window.SECURE_ORIGIN = "https://" + HOST + SECURE_PORT;

  //standard references
  window.SECURE_SUBDOMAIN_ORIGIN = "https://{{domains[www1]}}" + SECURE_PORT;
  window.SECURE_CROSS_SITE_ORIGIN = "https://" + CROSS_ORIGIN_HOST + SECURE_PORT;
  window.CROSS_SITE_HOST = CROSS_ORIGIN_HOST;

  // Set the global cookie name.
  window.HTTP_COOKIE = "cookie_via_http";
})();

// A tiny helper which returns the result of fetching |url| with credentials.
function credFetch(url) {
  return fetch(url, {"credentials": "include"})
    .then(response => {
      if (response.status !== 200) {
        throw new Error(response.statusText);
      }
      return response;
    });
}

// Returns a URL on |origin| which redirects to a given absolute URL.
function redirectTo(origin, url) {
  return origin + "/cookies/resources/redirectWithCORSHeaders.py?status=307&location=" + encodeURIComponent(url);
}

// Returns a URL on |origin| which navigates the window to the given URL (by
// setting window.location).
function navigateTo(origin, url) {
  return origin + "/cookies/resources/navigate.html?location=" + encodeURIComponent(url);
}

// Asserts that `document.cookie` contains or does not contain (according to
// the value of |present|) a cookie named |name| with a value of |value|.
function assert_dom_cookie(name, value, present) {
  var re = new RegExp("(?:^|; )" + name + "=" + value + "(?:$|;)");
  assert_equals(re.test(document.cookie), present, "`" + name + "=" + value + "` in `document.cookie`");
}

function assert_cookie(origin, obj, name, value, present) {
  assert_equals(obj[name], present ? value : undefined, "`" + name + "=" + value + "` in request to `" + origin + "`.");
}

// Remove the cookie named |name| from |origin|, then set it on |origin| anew.
// If |origin| matches `self.origin`, also assert (via `document.cookie`) that
// the cookie was correctly removed and reset.
function create_cookie(origin, name, value, extras) {
  alert("Create_cookie: " + origin + "/cookies/resources/drop.py?name=" + name);
  return credFetch(origin + "/cookies/resources/drop.py?name=" + name)
    .then(_ => {
      if (origin == self.origin)
        assert_dom_cookie(name, value, false);
    })
    .then(_ => {
      return credFetch(origin + "/cookies/resources/set.py?" + name + "=" + value + ";path=/;" + extras)
        .then(_ => {
          if (origin == self.origin)
            assert_dom_cookie(name, value, true);
        });
    });
}

//
// Prefix-specific test helpers
//
function set_prefixed_cookie_via_dom_test(options) {
  promise_test(t => {
    var name = options.prefix + "prefixtestcookie";
    erase_cookie_from_js(name, options.params);
    t.add_cleanup(() => erase_cookie_from_js(name, options.params));
    var value = "" + Math.random();
    document.cookie = name + "=" + value + ";" + options.params;

    assert_dom_cookie(name, value, options.shouldExistInDOM);

    return credFetch("/cookies/resources/list.py")
      .then(r => r.json())
      .then(cookies => assert_equals(cookies[name], options.shouldExistViaHTTP ? value : undefined));
  }, options.title);
}

function set_prefixed_cookie_via_http_test(options) {
  promise_test(t => {
    var name = options.prefix + "prefixtestcookie";
    var value = "" + Math.random();

    t.add_cleanup(() => {
      var cookie = name + "=0;expires=" + new Date(0).toUTCString() + ";" +
        options.params;

      return credFetch(options.origin + "/cookies/resources/set.py?" + cookie);
    });

    return credFetch(options.origin + "/cookies/resources/set.py?" + name + "=" + value + ";" + options.params)
      .then(_ => credFetch(options.origin + "/cookies/resources/list.py"))
      .then(r => r.json())
      .then(cookies => assert_equals(cookies[name], options.shouldExistViaHTTP ? value : undefined));
  }, options.title);
}

//
// SameSite-specific test helpers:
//

// status for "network" cookies.
window.SameSiteStatus = {
  CROSS_SITE: "cross-site",
  LAX: "lax",
  STRICT: "strict"
};
// status for "document.cookie".
window.DomSameSiteStatus = {
  CROSS_SITE: "cross-site",
  SAME_SITE: "same-site",
};

const wait_for_message = (type, origin) => {
  return new Promise((resolve, reject) => {
    window.addEventListener('message', e => {
      if (origin && e.origin != origin) {
        reject("Message from unexpected origin in wait_for_message:" + e.origin);
        return;
      }

      if (e.data.type && e.data.type === type)
        resolve(e);
    }, { once: true });
  });
};

// Reset SameSite test cookies on |origin|. If |origin| matches `self.origin`, assert
// (via `document.cookie`) that they were properly removed and reset.
async function resetSameSiteCookies(origin, value) {
  let w = window.open(origin + "/cookies/samesite/resources/puppet.html");
  try {
    await wait_for_message("READY", origin);
    w.postMessage({type: "drop", useOwnOrigin: true}, "*");
    await wait_for_message("drop-complete", origin);
    if (origin == self.origin) {
      assert_dom_cookie("samesite_strict", value, false);
      assert_dom_cookie("samesite_lax", value, false);
      assert_dom_cookie("samesite_none", value, false);
      assert_dom_cookie("samesite_unspecified", value, false);
    }

    w.postMessage({type: "set", value: value, useOwnOrigin: true}, "*");
    await wait_for_message("set-complete", origin);
    if (origin == self.origin) {
      assert_dom_cookie("samesite_strict", value, true);
      assert_dom_cookie("samesite_lax", value, true);
      assert_dom_cookie("samesite_none", value, true);
      assert_dom_cookie("samesite_unspecified", value, true);
    }
  } finally {
    w.close();
  }
}

// Given an |expectedStatus| and |expectedValue|, assert the |cookies| contains the
// proper set of cookie names and values, according to the legacy behavior where
// unspecified SameSite attribute defaults to SameSite=None behavior.
function verifySameSiteCookieStateLegacy(expectedStatus, expectedValue, cookies, domCookieStatus) {
    assert_equals(cookies["samesite_none"], expectedValue, "SameSite=None cookies are always sent.");
    assert_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are always sent.");
    if (expectedStatus == SameSiteStatus.CROSS_SITE) {
      assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not sent with cross-site requests.");
      assert_not_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are not sent with cross-site requests.");
    } else if (expectedStatus == SameSiteStatus.LAX) {
      assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not sent with lax requests.");
      assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are sent with lax requests.");
    } else if (expectedStatus == SameSiteStatus.STRICT) {
      assert_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are sent with strict requests.");
      assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are sent with strict requests.");
    }

    if (cookies["domcookies"]) {
      verifyDocumentCookieLegacy(domCookieStatus, expectedValue, cookies["domcookies"]);
    }
}

// Same as above except this expects samesite_unspecified to act the same as
// samesite_lax (which is the behavior expected when SameSiteByDefault is
// enabled).
function verifySameSiteCookieStateWithSameSiteByDefault(expectedStatus, expectedValue, cookies, domCookieStatus) {
    assert_equals(cookies["samesite_none"], expectedValue, "SameSite=None cookies are always sent.");
    if (expectedStatus == SameSiteStatus.CROSS_SITE) {
      assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not sent with cross-site requests.");
      assert_not_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are not sent with cross-site requests.");
      assert_not_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are not sent with cross-site requests.");
    } else if (expectedStatus == SameSiteStatus.LAX) {
      assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not sent with lax requests.");
      assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are sent with lax requests.");
      assert_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are are sent with lax requests.")
    } else if (expectedStatus == SameSiteStatus.STRICT) {
      assert_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are sent with strict requests.");
      assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are sent with strict requests.");
      assert_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are are sent with strict requests.")
    }

    if (cookies["domcookies"]) {
      verifyDocumentCookieWithSameSiteByDefault(domCookieStatus, expectedValue, cookies["domcookies"]);
    }
}

function verifyDocumentCookieLegacy(expectedStatus, expectedValue, domcookies) {
  const cookies = domcookies.split(";")
                            .map(cookie => cookie.trim().split("="))
                            .reduce((obj, cookie) => {
                              obj[cookie[0]] = cookie[1];
                              return obj;
                            }, {});

  if (expectedStatus == DomSameSiteStatus.SAME_SITE) {
    assert_equals(cookies["samesite_none"], expectedValue, "SameSite=None cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are always included in document.cookie.");
  } else if (expectedStatus == DomSameSiteStatus.CROSS_SITE) {
    assert_equals(cookies["samesite_none"], expectedValue, "SameSite=None cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are always included in document.cookie.");
    assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not included in document.cookie when cross-site.");
    assert_not_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are not included in document.cookie when cross-site.");
  }
}

function verifyDocumentCookieWithSameSiteByDefault(expectedStatus, expectedValue, domcookies) {
  const cookies = domcookies.split(";")
                            .map(cookie => cookie.trim().split("="))
                            .reduce((obj, cookie) => {
                              obj[cookie[0]] = cookie[1];
                              return obj;
                            }, {});

  if (expectedStatus == DomSameSiteStatus.SAME_SITE) {
    assert_equals(cookies["samesite_none"], expectedValue, "SameSite=None cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are always included in document.cookie.");
    assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are always included in document.cookie.");
  } else if (expectedStatus == DomSameSiteStatus.CROSS_SITE) {
    assert_equals(cookies["samesite_none"], expectedValue, "SameSite=None cookies are always included in document.cookie.");
    assert_not_equals(cookies["samesite_unspecified"], expectedValue, "Unspecified-SameSite cookies are not included in document.cookie when cross-site.");
    assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not included in document.cookie when cross-site.");
    assert_not_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are not included in document.cookie when cross-site.");
  }
}

function isLegacySameSite() {
  return location.search === "?legacy-samesite";
}

// Get the proper verifier based on the test's variant type.
function getSameSiteVerifier() {
  return isLegacySameSite() ?
      verifySameSiteCookieStateLegacy : verifySameSiteCookieStateWithSameSiteByDefault;
}

//
// LeaveSecureCookiesAlone-specific test helpers:
//

window.SecureStatus = {
  INSECURE_COOKIE_ONLY: "1",
  BOTH_COOKIES: "2",
};

//Reset SameSite test cookies on |origin|. If |origin| matches `self.origin`, assert
//(via `document.cookie`) that they were properly removed and reset.
function resetSecureCookies(origin, value) {
return credFetch(origin + "/cookies/resources/dropSecure.py")
 .then(_ => {
   if (origin == self.origin) {
     assert_dom_cookie("alone_secure", value, false);
     assert_dom_cookie("alone_insecure", value, false);
   }
 })
 .then(_ => {
     return credFetch(origin + "/cookie/resources/setSecure.py?" + value)
 })
}

// Reset SameSite=None test cookies on |origin|. If |origin| matches
// `self.origin`, assert (via `document.cookie`) that they were properly
// removed.
function resetSameSiteNoneCookies(origin, value) {
  return credFetch(origin + "/cookies/resources/dropSameSiteNone.py")
    .then(_ => {
      if (origin == self.origin) {
        assert_dom_cookie("samesite_none_insecure", value, false);
        assert_dom_cookie("samesite_none_secure", value, false);
      }
    })
    .then(_ => {
      return credFetch(origin + "/cookies/resources/setSameSiteNone.py?" + value);
    })
}

// Reset test cookies with multiple SameSite attributes on |origin|.
// If |origin| matches `self.origin`, assert (via `document.cookie`)
// that they were properly removed.
function resetSameSiteMultiAttributeCookies(origin, value) {
  return credFetch(origin + "/cookies/resources/dropSameSiteMultiAttribute.py")
    .then(_ => {
      if (origin == self.origin) {
        assert_dom_cookie("samesite_unsupported", value, false);
        assert_dom_cookie("samesite_unsupported_none", value, false);
        assert_dom_cookie("samesite_unsupported_lax", value, false);
        assert_dom_cookie("samesite_unsupported_strict", value, false);
        assert_dom_cookie("samesite_none_unsupported", value, false);
        assert_dom_cookie("samesite_lax_unsupported", value, false);
        assert_dom_cookie("samesite_strict_unsupported", value, false);
        assert_dom_cookie("samesite_lax_none", value, false);
      }
    })
    .then(_ => {
      return credFetch(origin + "/cookies/resources/setSameSiteMultiAttribute.py?" + value);
    })
}

//
// DOM based cookie manipulation APIs
//

// erase cookie value and set for expiration
function erase_cookie_from_js(name, params) {
  document.cookie = `${name}=0; expires=${new Date(0).toUTCString()}; ${params};`;
  var re = new RegExp("(?:^|; )" + name);
  assert_equals(re.test(document.cookie), false, "Sanity check: " + name + " has been deleted.");
}