summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/cookies/samesite
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/cookies/samesite
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/cookies/samesite')
-rw-r--r--testing/web-platform/tests/cookies/samesite/about-blank-nested.https.html29
-rw-r--r--testing/web-platform/tests/cookies/samesite/about-blank-subresource.https.html31
-rw-r--r--testing/web-platform/tests/cookies/samesite/about-blank-toplevel.https.html30
-rw-r--r--testing/web-platform/tests/cookies/samesite/fetch.https.html40
-rw-r--r--testing/web-platform/tests/cookies/samesite/form-get-blank-reload.https.html66
-rw-r--r--testing/web-platform/tests/cookies/samesite/form-get-blank.https.html68
-rw-r--r--testing/web-platform/tests/cookies/samesite/form-post-blank-reload.https.html56
-rw-r--r--testing/web-platform/tests/cookies/samesite/form-post-blank.https.html57
-rw-r--r--testing/web-platform/tests/cookies/samesite/get_all_cookies-default-samesite.html20
-rw-r--r--testing/web-platform/tests/cookies/samesite/get_named_cookie-default-samesite.html18
-rw-r--r--testing/web-platform/tests/cookies/samesite/iframe-reload.https.html55
-rw-r--r--testing/web-platform/tests/cookies/samesite/iframe.document.https.html57
-rw-r--r--testing/web-platform/tests/cookies/samesite/iframe.https.html79
-rw-r--r--testing/web-platform/tests/cookies/samesite/img.https.html75
-rw-r--r--testing/web-platform/tests/cookies/samesite/multiple-samesite-attributes.https.html92
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/echo-cookies.html8
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/iframe-navigate-report.html3
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/iframe-subresource-report.html14
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/iframe.document.html8
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/navigate-iframe.html26
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/navigate.html25
-rw-r--r--testing/web-platform/tests/cookies/samesite/resources/puppet.html32
-rw-r--r--testing/web-platform/tests/cookies/samesite/sandbox-iframe-nested.https.html28
-rw-r--r--testing/web-platform/tests/cookies/samesite/sandbox-iframe-subresource.https.html28
-rw-r--r--testing/web-platform/tests/cookies/samesite/setcookie-lax.https.html32
-rw-r--r--testing/web-platform/tests/cookies/samesite/setcookie-navigation.https.html81
-rw-r--r--testing/web-platform/tests/cookies/samesite/window-open-reload.https.html52
-rw-r--r--testing/web-platform/tests/cookies/samesite/window-open.https.html54
28 files changed, 1164 insertions, 0 deletions
diff --git a/testing/web-platform/tests/cookies/samesite/about-blank-nested.https.html b/testing/web-platform/tests/cookies/samesite/about-blank-nested.https.html
new file mode 100644
index 0000000000..d5c9b8ada3
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/about-blank-nested.https.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/cookies/resources/cookie-helper.sub.js"></script>
+</head>
+<body onload="doTests()">
+ <iframe src="about:blank" id="if">
+ </iframe>
+ <script>
+ function doTests() {
+ promise_test(async function(t) {
+ var child = document.getElementById("if");
+ var grandKid = child.contentDocument.createElement("iframe");
+ child.contentDocument.body.appendChild(grandKid);
+ var value = "" + Math.random();
+ await resetSameSiteCookies(SECURE_ORIGIN, value);
+
+ // Using postToParent.py here to see cookies used when navigating the page.
+ grandKid.src = SECURE_ORIGIN + "/cookies/resources/postToParent.py"
+ var e = await wait_for_message("COOKIES", SECURE_ORIGIN);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_unspecified", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_lax", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_strict", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_none", value, true);
+ }, "SameSite cookies with intervening about:blank iframes and navigation");
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/cookies/samesite/about-blank-subresource.https.html b/testing/web-platform/tests/cookies/samesite/about-blank-subresource.https.html
new file mode 100644
index 0000000000..0a19f30d34
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/about-blank-subresource.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/cookies/resources/cookie-helper.sub.js"></script>
+</head>
+<body onload="doTests()">
+ <script>
+ function doTests() {
+ promise_test(async function(t) {
+ var child = window.open("");
+ child.onmessage = (ev) => {
+ child.opener.postMessage(ev.data, '*');
+ };
+ var grandKid = child.document.createElement("iframe");
+ child.document.body.appendChild(grandKid);
+ var value = "" + Math.random();
+ await resetSameSiteCookies(SECURE_ORIGIN, value);
+
+ // Load at what cookies a subresource below an about:blank iframe
+ // inheritting this origin gets.
+ grandKid.src = SECURE_ORIGIN + "/cookies/samesite/resources/iframe-subresource-report.html"
+ var e = await wait_for_message("COOKIES", SECURE_ORIGIN);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_unspecified", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_lax", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_strict", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_none", value, true);
+ }, "SameSite cookies on subresource of top-level about:blank window");
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/cookies/samesite/about-blank-toplevel.https.html b/testing/web-platform/tests/cookies/samesite/about-blank-toplevel.https.html
new file mode 100644
index 0000000000..3a4dde7673
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/about-blank-toplevel.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/cookies/resources/cookie-helper.sub.js"></script>
+</head>
+<body onload="doTests()">
+ <script>
+ function doTests() {
+ promise_test(async function(t) {
+ var child = window.open("");
+ child.onmessage = (ev) => {
+ child.opener.postMessage(ev.data, '*');
+ };
+ var grandKid = child.document.createElement("iframe");
+ child.document.body.appendChild(grandKid);
+ var value = "" + Math.random();
+ await resetSameSiteCookies(SECURE_ORIGIN, value);
+
+ // Using postToParent.py here to see cookies used when navigating the page.
+ grandKid.src = SECURE_ORIGIN + "/cookies/resources/postToParent.py"
+ var e = await wait_for_message("COOKIES", SECURE_ORIGIN);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_unspecified", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_lax", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_strict", value, true);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_none", value, true);
+ }, "SameSite cookies with top-level about:blank window");
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/cookies/samesite/fetch.https.html b/testing/web-platform/tests/cookies/samesite/fetch.https.html
new file mode 100644
index 0000000000..79e49009fb
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/fetch.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ function create_test(origin, target, expectedStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return credFetch(target + "/cookies/resources/list.py")
+
+ .then(r => r.json())
+ .then(cookies => verifySameSiteCookieState(expectedStatus, value, cookies, DomSameSiteStatus.SAME_SITE));
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, "Same-host fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain fetches are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site fetches are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host fetches are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host fetches are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to same-host fetches are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to subdomain fetches are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site fetches are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site fetches are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site fetches are cross-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/form-get-blank-reload.https.html b/testing/web-platform/tests/cookies/samesite/form-get-blank-reload.https.html
new file mode 100644
index 0000000000..b5ab8ade91
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/form-get-blank-reload.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ // This test creates a form whose submission GETs the page postToParent.py
+ // (on the specified origin) in a popup window. The popup sends a postMessage
+ // event back to its opener (i.e., here) with the cookies it received, which
+ // we verify against expectedStatus. Then, the test sends a message to the
+ // popup, telling it to reload itself via window.location.reload(). Again,
+ // the popup posts a message back here with the cookies it received. These
+ // cookies are verified against expectedStatusReload.
+ function create_test(origin, target, expectedStatus, expectedStatusReload, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var f = document.createElement('form');
+ f.action = target + "/cookies/resources/postToParent.py";
+ f.target = "_blank";
+ f.method = "GET";
+ f.rel = "opener";
+
+ // If |target| contains a `redir` parameter, extract it, and add it
+ // to the form so it doesn't get dropped in the submission.
+ var url = new URL(f.action);
+ if (url.pathname = "/cookies/rfc6265/resources/redirectWithCORSHeaders.py") {
+ var i = document.createElement("input");
+ i.name = "location";
+ i.value = url.searchParams.get("location");
+ i.type = "hidden";
+ f.appendChild(i);
+ }
+ var reloaded = false;
+ var msgHandler = e => {
+ try {
+ verifySameSiteCookieState(reloaded ? expectedStatusReload : expectedStatus, value, e.data, DomSameSiteStatus.SAME_SITE);
+ } catch (e) {
+ reject(e);
+ }
+
+ if (reloaded) {
+ window.removeEventListener("message", msgHandler);
+ e.source.close();
+ resolve("Popup received the cookie.");
+ } else {
+ reloaded = true;
+ e.source.postMessage("reload", "*");
+ }
+ };
+ window.addEventListener("message", msgHandler);
+ document.body.appendChild(f);
+
+ f.submit();
+ });
+ });
+ }, title);
+ }
+
+ // The reload status is always strictly same-site because this is a site-initiated reload, as opposed to a reload triggered by a user interface element.
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, SameSiteStatus.STRICT, "Reloaded same-host top-level form GETs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, SameSiteStatus.STRICT, "Reloaded subdomain top-level form GETs are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.LAX, SameSiteStatus.STRICT, "Reloaded cross-site top-level form GETs are strictly same-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/form-get-blank.https.html b/testing/web-platform/tests/cookies/samesite/form-get-blank.https.html
new file mode 100644
index 0000000000..2fe81b2b56
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/form-get-blank.https.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ function create_test(origin, target, expectedStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var f = document.createElement('form');
+ f.action = target + "/cookies/resources/postToParent.py";
+ f.target = "_blank";
+ f.method = "GET";
+ f.rel = "opener";
+
+ // If |target| contains a `redir` parameter, extract it, and add it
+ // to the form so it doesn't get dropped in the submission.
+ var url = new URL(f.action);
+ if (url.pathname == "/cookies/resources/redirectWithCORSHeaders.py") {
+ var i = document.createElement("input");
+ i.name = "location";
+ i.type="hidden";
+ i.value = url.searchParams.get("location");
+ f.appendChild(i);
+ }
+
+ var msgHandler = e => {
+ window.removeEventListener("message", msgHandler);
+ e.source.close();
+ try {
+ verifySameSiteCookieState(expectedStatus, value, e.data, DomSameSiteStatus.SAME_SITE);
+ resolve("Popup received the cookie.");
+ } catch (e) {
+ reject(e);
+ }
+ };
+ window.addEventListener("message", msgHandler);
+ document.body.appendChild(f);
+ f.submit();
+ });
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, "Same-host top-level form GETs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain top-level form GETs are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.LAX, "Cross-site top-level form GETs are laxly same-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host top-level form GETs are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host top-level form GETs are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to same-host top-level form GETs are laxly same-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain top-level form GETs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain top-level form GETs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to subdomain top-level form GETs are laxly same-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Same-host redirecting to cross-site top-level form GETs are laxly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Subdomain redirecting to cross-site top-level form GETs are laxly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to cross-site top-level form GETs are laxly same-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/form-post-blank-reload.https.html b/testing/web-platform/tests/cookies/samesite/form-post-blank-reload.https.html
new file mode 100644
index 0000000000..cdbb89ace5
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/form-post-blank-reload.https.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ // This test creates a form whose submission POSTs to the page postToParent.py
+ // (on the specified origin) in a popup window. The popup sends a postMessage
+ // event back to its opener (i.e., here) with the cookies it received, which
+ // we verify against expectedStatus. Then, the test sends a message to the
+ // popup, telling it to reload itself via window.location.reload(). Again,
+ // the popup posts a message back here with the cookies it received. These
+ // cookies are verified against expectedStatusReload.
+ function create_test(origin, target, expectedStatus, expectedStatusReload, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var f = document.createElement('form');
+ f.action = target + "/cookies/resources/postToParent.py";
+ f.target = "_blank";
+ f.method = "POST";
+ f.rel = "opener";
+
+ var reloaded = false;
+ var msgHandler = e => {
+ try {
+ verifySameSiteCookieState(reloaded ? expectedStatusReload : expectedStatus, value, e.data, DomSameSiteStatus.SAME_SITE);
+ } catch (e) {
+ reject(e);
+ }
+
+ if (reloaded) {
+ window.removeEventListener("message", msgHandler);
+ e.source.close();
+ resolve("Popup received the cookie.");
+ } else {
+ reloaded = true;
+ e.source.postMessage("reload", "*");
+ }
+ };
+ window.addEventListener("message", msgHandler);
+
+ document.body.appendChild(f);
+ f.submit();
+ });
+ });
+ }, title);
+ }
+
+ // The reload status is always strictly same-site because this is a site-initiated reload, as opposed to a reload triggered by a user interface element.
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, SameSiteStatus.STRICT, "Reloaded same-host top-level form POSTs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, SameSiteStatus.STRICT, "Reloaded subdomain top-level form POSTs are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, SameSiteStatus.STRICT, "Reloaded cross-site top-level form POSTs are strictly same-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/form-post-blank.https.html b/testing/web-platform/tests/cookies/samesite/form-post-blank.https.html
new file mode 100644
index 0000000000..947853893d
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/form-post-blank.https.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ function create_test(origin, target, expectedStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var f = document.createElement('form');
+ f.action = target + "/cookies/resources/postToParent.py";
+ f.target = "_blank";
+ f.method = "POST";
+ f.rel = "opener";
+
+ var msgHandler = e => {
+ window.removeEventListener("message", msgHandler);
+ e.source.close();
+ try {
+ verifySameSiteCookieState(expectedStatus, value, e.data, DomSameSiteStatus.SAME_SITE);
+ resolve("Popup received the cookie.");
+ } catch (e) {
+ reject(e);
+ }
+ };
+ window.addEventListener("message", msgHandler);
+ document.body.appendChild(f);
+ f.submit();
+ });
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, "Same-host top-level form POSTs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain top-level form POSTs are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site top-level form POSTs are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host top-level form POSTs are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host top-level form POSTs are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to same-host top-level form POSTs are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain top-level form POSTs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain top-level form POSTs are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to subdomain top-level form POSTs are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site top-level form POSTs are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site top-level form POSTs are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site top-level form POSTs are cross-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/get_all_cookies-default-samesite.html b/testing/web-platform/tests/cookies/samesite/get_all_cookies-default-samesite.html
new file mode 100644
index 0000000000..3b1606b7f8
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/get_all_cookies-default-samesite.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>TestDriver get_all_cookies method w/ default SameSite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+promise_test(async t => {
+ await test_driver.delete_all_cookies();
+ t.add_cleanup(test_driver.delete_all_cookies);
+ document.cookie = "test0=0";
+ const cookies = await test_driver.get_all_cookies();
+ assert_equals(cookies.length, 1);
+ const cookie = cookies[0];
+ assert_equals(cookie["name"], "test0");
+ assert_equals(cookie["value"], "0");
+ assert_equals(cookie["sameSite"], "Lax");
+}, "Get all cookies w/ default SameSite");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/get_named_cookie-default-samesite.html b/testing/web-platform/tests/cookies/samesite/get_named_cookie-default-samesite.html
new file mode 100644
index 0000000000..2ee5d0f29c
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/get_named_cookie-default-samesite.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>TestDriver get_named_cookie method w/ default SameSite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+promise_test(async t => {
+ await test_driver.delete_all_cookies();
+ t.add_cleanup(test_driver.delete_all_cookies);
+ document.cookie = "test0=0";
+ const cookie = await test_driver.get_named_cookie("test0");
+ assert_equals(cookie["name"], "test0");
+ assert_equals(cookie["value"], "0");
+ assert_equals(cookie["sameSite"], "Lax");
+}, "Get Named cookie w/ default SameSite");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/iframe-reload.https.html b/testing/web-platform/tests/cookies/samesite/iframe-reload.https.html
new file mode 100644
index 0000000000..d1916a805c
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/iframe-reload.https.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<!-- We're appending an <iframe> to the document's body, so execute tests after we have a body -->
+<body>
+<script>
+ // This test creates an iframe with postToParent.py on the specified origin,
+ // which sends a postMessage event with the cookies it received back to the
+ // parent (i.e., here). Upon receiving the message, the test verifies that the
+ // correct cookies were sent to the iframe, and posts a message back to the
+ // iframe telling it to reload itself. Upon reload, the iframe sends a
+ // postMessage event back to the test with the cookies it received, which are
+ // again verified.
+ function create_test(origin, target, expectedStatus, expectedDomStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var iframe = document.createElement("iframe");
+ iframe.onerror = _ => reject("IFrame could not be loaded.");
+
+ var reloaded = false;
+ var msgHandler = e => {
+ try {
+ verifySameSiteCookieState(expectedStatus, value, e.data, expectedDomStatus);
+ } catch (e) {
+ reject(e);
+ }
+
+ if (reloaded) {
+ window.removeEventListener("message", msgHandler);
+ document.body.removeChild(iframe);
+ resolve("IFrame received the cookie.");
+ } else {
+ reloaded = true;
+ e.source.postMessage("reload", "*");
+ }
+ };
+ window.addEventListener("message", msgHandler);
+
+ iframe.src = target + "/cookies/resources/postToParent.py";
+ document.body.appendChild(iframe);
+ });
+ });
+ }, title);
+ }
+
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Reloaded same-host fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Reloaded subdomain fetches are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Reloaded cross-site fetches are cross-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/iframe.document.https.html b/testing/web-platform/tests/cookies/samesite/iframe.document.https.html
new file mode 100644
index 0000000000..2d276dbcaa
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/iframe.document.https.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<!-- We're appending an <iframe> to the document's body, so execute tests after we have a body -->
+<body>
+<script>
+ function create_test(target, expectedDomStatus, title) {
+ promise_test(async t => {
+ let cookieValue = await new Promise((resolve, reject) => {
+ var iframe = document.createElement("iframe");
+
+ window.onmessage = t.step_func(e => {
+ if (e.source == iframe.contentWindow) {
+ document.body.removeChild(iframe);
+ resolve(e.data.value);
+ }
+ });
+
+ iframe.src = target + "/cookies/samesite/resources/iframe.document.html";
+ document.body.appendChild(iframe);
+ });
+
+ await new Promise((resolve, reject) => {
+ var iframe = document.createElement("iframe");
+
+ window.onmessage = t.step_func(e => {
+ if (e.source == iframe.contentWindow) {
+ // Cleanup, then verify cookie state:
+ document.body.removeChild(iframe);
+
+ const cookies = e.data;
+ assert_equals(cookies["dc_samesite_none"], cookieValue, "SameSite=none cookies can be set via document.cookies even by cross-origin documents");
+
+ if (expectedDomStatus === DomSameSiteStatus.SAME_SITE) {
+ assert_equals(cookies["dc_samesite_lax"], cookieValue, "SameSite=lax cookies can be set via document.cookies by same-site documents");
+ assert_equals(cookies["dc_samesite_strict"], cookieValue, "SameSite=strict cookies can be set via document.cookies by same-site documents");
+ } else if (expectedDomStatus === DomSameSiteStatus.CROSS_SITE) {
+ assert_not_equals(cookies["dc_samesite_lax"], cookieValue, "SameSite=lax cookies can be set via document.cookies by same-site documents");
+ assert_not_equals(cookies["dc_samesite_strict"], cookieValue, "SameSite=strict cookies can be set via document.cookies by same-site documents");
+ }
+
+ resolve();
+ }
+ });
+
+ iframe.src = target + "/cookies/resources/postToParent.py";
+ document.body.appendChild(iframe);
+ });
+ }, title);
+ }
+
+ create_test(SECURE_ORIGIN, DomSameSiteStatus.SAME_SITE, "Same-site iframes can set lax/strict cookies via document.cookie");
+ create_test(SECURE_CROSS_SITE_ORIGIN, DomSameSiteStatus.CROSS_SITE, "Cross-site iframe cannot set lax/strict cookies via document.cookie");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/iframe.https.html b/testing/web-platform/tests/cookies/samesite/iframe.https.html
new file mode 100644
index 0000000000..31b34ccf55
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/iframe.https.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<!-- We're appending an <iframe> to the document's body, so execute tests after we have a body -->
+<body>
+<script>
+ // This test creates an iframe with postToParent.py on the specified origin,
+ // which sends a postMessage event with the cookies it received back to the
+ // parent (i.e., here). Upon receiving the message, the test verifies that the
+ // correct cookies were sent to the iframe.
+ function create_test(origin, target, expectedStatus, expectedDomStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var iframe = document.createElement("iframe");
+ iframe.onerror = _ => reject("IFrame could not be loaded.");
+
+ var msgHandler = e => {
+ if (e.source == iframe.contentWindow) {
+ // Cleanup, then verify cookie state:
+ document.body.removeChild(iframe);
+ window.removeEventListener("message", msgHandler);
+ try {
+ verifySameSiteCookieState(expectedStatus, value, e.data, expectedDomStatus);
+ resolve();
+ } catch(e) {
+ reject(e);
+ }
+ }
+ };
+ window.addEventListener("message", msgHandler);
+
+ iframe.src = target + "/cookies/resources/postToParent.py";
+ document.body.appendChild(iframe);
+ });
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Same-host fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Subdomain fetches are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Cross-site fetches are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Same-host redirecting to same-host fetches are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Subdomain redirecting to same-host fetches are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.SAME_SITE, "Cross-site redirecting to same-host fetches are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to subdomain:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Same-host redirecting to subdomain fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Subdomain redirecting to subdomain fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.SAME_SITE, "Cross-site redirecting to subdomain fetches are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site fetches are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site fetches are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site fetches are cross-site");
+
+ // Navigate from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, navigateTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Same-host navigating to same-host fetches are strictly same-site");
+ create_test(SECURE_ORIGIN, navigateTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Subdomain navigating to same-host fetches are strictly same-site");
+ create_test(SECURE_ORIGIN, navigateTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.SAME_SITE, "Cross-site navigating to same-host fetches are cross-site");
+
+ // Navigate from {same-host,subdomain,cross-site} to subdomain:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, navigateTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Same-host navigating to subdomain fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, navigateTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, DomSameSiteStatus.SAME_SITE, "Subdomain navigating to subdomain fetches are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, navigateTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.SAME_SITE, "Cross-site navigating to subdomain fetches are cross-site-site");
+
+ // Navigate from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, navigateTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Same-host navigating to cross-site fetches are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, navigateTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Subdomain navigating to cross-site fetches are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, navigateTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, DomSameSiteStatus.CROSS_SITE, "Cross-site navigating to cross-site fetches are cross-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/img.https.html b/testing/web-platform/tests/cookies/samesite/img.https.html
new file mode 100644
index 0000000000..1ddc8d99ad
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/img.https.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ function assert_cookie_present(origin, name, value) {
+ return new Promise((resolve, reject) => {
+ var img = document.createElement("img");
+ img.onload = _ => resolve("'" + name + "=" + value + "' present on " + origin);
+ img.onerror = _ => reject("'" + name + "=" + value + "' not present on " + origin);
+
+ // We need to URL encode the destination path/query if we're redirecting:
+ if (origin.match(/\/redir/))
+ img.src = origin + encodeURIComponent("/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value);
+ else
+ img.src = origin + "/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value;
+ });
+ }
+
+ function assert_cookie_absent(origin, name, value) {
+ return new Promise((resolve, reject) => {
+ var img = document.createElement("img");
+ img.onload = _ => reject("'" + name + "=" + value + "' present on " + origin);
+ img.onerror = _ => resolve("'" + name + "=" + value + "' not present on " + origin);
+
+ // We need to URL encode the destination path/query if we're redirecting:
+ if (origin.match(/\/redir/))
+ img.src = origin + encodeURIComponent("/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value);
+ else
+ img.src = origin + "/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value;
+ });
+ }
+
+ function create_test(origin, target, expectedStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ var asserts = [assert_cookie_present(target, "samesite_none", value),
+ expectedStatus == SameSiteStatus.STRICT ?
+ assert_cookie_present(target, "samesite_strict", value) :
+ assert_cookie_absent(target, "samesite_strict", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_lax", value) :
+ assert_cookie_present(target, "samesite_lax", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_unspecified", value) :
+ assert_cookie_present(target, "samesite_unspecified", value)];
+ return Promise.all(asserts);
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, "Same-host images are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain images are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site images are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host images are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host images are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to same-host images are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain images are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain images are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to subdomain images are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site images are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site images are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site images are cross-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/multiple-samesite-attributes.https.html b/testing/web-platform/tests/cookies/samesite/multiple-samesite-attributes.https.html
new file mode 100644
index 0000000000..d32a39639d
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/multiple-samesite-attributes.https.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ function assert_cookie_present(origin, name, value) {
+ return new Promise((resolve, reject) => {
+ var img = document.createElement("img");
+ img.onload = _ => resolve("'" + name + "=" + value + "' present on " + origin);
+ img.onerror = _ => reject("'" + name + "=" + value + "' not present on " + origin);
+
+ // We need to URL encode the destination path/query if we're redirecting:
+ if (origin.match(/\/redir/))
+ img.src = origin + encodeURIComponent("/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value);
+ else
+ img.src = origin + "/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value;
+ });
+ }
+
+ function assert_cookie_absent(origin, name, value) {
+ return new Promise((resolve, reject) => {
+ var img = document.createElement("img");
+ img.onload = _ => reject("'" + name + "=" + value + "' present on " + origin);
+ img.onerror = _ => resolve("'" + name + "=" + value + "' not present on " + origin);
+
+ // We need to URL encode the destination path/query if we're redirecting:
+ if (origin.match(/\/redir/))
+ img.src = origin + encodeURIComponent("/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value);
+ else
+ img.src = origin + "/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value;
+ });
+ }
+
+ function create_test(origin, target, expectedStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteMultiAttributeCookies(origin, value)
+ .then(_ => {
+ var asserts = [
+ assert_cookie_present(target, "samesite_unsupported_none", value),
+ assert_cookie_present(target, "samesite_lax_none", value),
+ expectedStatus == SameSiteStatus.STRICT ?
+ assert_cookie_present(target, "samesite_unsupported_strict", value) :
+ assert_cookie_absent(target, "samesite_unsupported_strict", value),
+ expectedStatus == SameSiteStatus.STRICT ?
+ assert_cookie_present(target, "samesite_lax_strict", value) :
+ assert_cookie_absent(target, "samesite_lax_strict", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_unsupported_lax", value) :
+ assert_cookie_present(target, "samesite_unsupported_lax", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_strict_lax", value) :
+ assert_cookie_present(target, "samesite_strict_lax", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_none_unsupported", value) :
+ assert_cookie_present(target, "samesite_none_unsupported", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_lax_unsupported", value) :
+ assert_cookie_present(target, "samesite_lax_unsupported", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_strict_unsupported", value) :
+ assert_cookie_present(target, "samesite_strict_unsupported", value),
+ expectedStatus == SameSiteStatus.CROSS_SITE ?
+ assert_cookie_absent(target, "samesite_unsupported", value) :
+ assert_cookie_present(target, "samesite_unsupported", value)];
+ return Promise.all(asserts);
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, "Same-host images are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain images are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site images are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host images are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host images are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to same-host images are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain images are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain images are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to subdomain images are cross-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site images are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site images are cross-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site images are cross-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/resources/echo-cookies.html b/testing/web-platform/tests/cookies/samesite/resources/echo-cookies.html
new file mode 100644
index 0000000000..a1b29b9b03
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/echo-cookies.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script>
+ if (window.opener)
+ window.opener.postMessage({ type: 'COOKIES_SET', cookies: document.cookie }, '*');
+ if (window.parent !== window)
+ window.parent.postMessage({ type: 'FRAME_COOKIES_SET', cookies: document.cookie }, '*');
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/resources/iframe-navigate-report.html b/testing/web-platform/tests/cookies/samesite/resources/iframe-navigate-report.html
new file mode 100644
index 0000000000..98ea469fda
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/iframe-navigate-report.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<iframe src="/cookies/resources/postToParent.py">
+</iframe>
diff --git a/testing/web-platform/tests/cookies/samesite/resources/iframe-subresource-report.html b/testing/web-platform/tests/cookies/samesite/resources/iframe-subresource-report.html
new file mode 100644
index 0000000000..1dceb4e436
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/iframe-subresource-report.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<head>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+function reportSubresourceCookies() {
+ credFetch(SECURE_ORIGIN + "/cookies/resources/list.py")
+ .then(r => r.json())
+ .then(cookies => { cookies.type = "COOKIES";
+ target = window.opener ? window.opener : window.parent;
+ target.postMessage(cookies, "*");});
+}
+</script>
+</head>
+<body onload="reportSubresourceCookies()">
diff --git a/testing/web-platform/tests/cookies/samesite/resources/iframe.document.html b/testing/web-platform/tests/cookies/samesite/resources/iframe.document.html
new file mode 100644
index 0000000000..7026beb7e8
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/iframe.document.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script>
+ var value = "" + Math.random();
+ document.cookie = `dc_samesite_strict=${value}; secure; sameSite=strict; path=/`;
+ document.cookie = `dc_samesite_lax=${value}; secure; sameSite=lax; path=/`;
+ document.cookie = `dc_samesite_none=${value}; secure; sameSite=none; path=/`;
+ parent.postMessage({value}, "*");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/resources/navigate-iframe.html b/testing/web-platform/tests/cookies/samesite/resources/navigate-iframe.html
new file mode 100644
index 0000000000..98ad6264fa
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/navigate-iframe.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ window.addEventListener('load', function() {
+ window.opener.postMessage({ type: 'LOADED' }, '*');
+ });
+
+ window.addEventListener('message', function(e) {
+ if (SECURE_ORIGIN !== window.location.origin)
+ return;
+
+ if (e.data.type === "initialize-iframe")
+ window.frames[0].location = e.data.url;
+ if (e.data.type === "navigate-iframe")
+ window.frames[0].postMessage({ type: 'navigate', url: e.data.url }, '*');
+
+ // Relay messages sent by the subframe to the opener.
+ if (e.data.type === 'FRAME_READY')
+ window.opener.postMessage({ type: 'FRAME_READY' }, '*');
+
+ if (e.data.type === 'FRAME_COOKIES_SET')
+ window.opener.postMessage({ type: 'FRAME_COOKIES_SET', cookies: e.data.cookies }, '*');
+ });
+</script>
+<iframe></iframe>
diff --git a/testing/web-platform/tests/cookies/samesite/resources/navigate.html b/testing/web-platform/tests/cookies/samesite/resources/navigate.html
new file mode 100644
index 0000000000..88de6dff92
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/navigate.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ window.addEventListener('load', function() {
+ if (window.opener)
+ window.opener.postMessage({ type: 'READY' }, '*');
+ if (window.parent !== window)
+ window.parent.postMessage({ type: 'FRAME_READY' }, '*');
+ });
+
+ window.addEventListener('message', function(e) {
+ if (e.data.type === "navigate") {
+ window.location = e.data.url;
+ }
+
+ if (e.data.type === "post-form") {
+ var f = document.createElement('form');
+ f.action = e.data.url;
+ f.method = "POST";
+ document.body.appendChild(f);
+ f.submit();
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/resources/puppet.html b/testing/web-platform/tests/cookies/samesite/resources/puppet.html
new file mode 100644
index 0000000000..6d36132d3a
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/resources/puppet.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ // Helper to either set or clear some cookies on its own origin, or
+ // (potentially) cross-site on SECURE_ORIGIN.
+ window.onmessage = e => {
+ var originToUse = SECURE_ORIGIN;
+ if (e.data.useOwnOrigin)
+ originToUse = self.origin;
+
+ if (e.data.type === "set") {
+ credFetch(originToUse + "/cookies/resources/setSameSite.py?" + e.data.value)
+ .then(_ => {
+ e.source.postMessage({
+ type: "set-complete",
+ value: e.data.value
+ }, "*");
+ });
+ }
+
+ if (e.data.type === "drop") {
+ credFetch(originToUse + "/cookies/resources/dropSameSite.py")
+ .then(_ => {
+ e.source.postMessage({type: "drop-complete"}, "*");
+ });
+ }
+ };
+
+ window.opener.postMessage({
+ type: "READY"
+ }, "*");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/sandbox-iframe-nested.https.html b/testing/web-platform/tests/cookies/samesite/sandbox-iframe-nested.https.html
new file mode 100644
index 0000000000..310f86a446
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/sandbox-iframe-nested.https.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/cookies/resources/cookie-helper.sub.js"></script>
+</head>
+<body onload="doTests()">
+ <iframe id="if" sandbox="allow-scripts">
+ </iframe>
+ <script>
+ function doTests() {
+ promise_test(async function(t) {
+ var value = "" + Math.random();
+ await resetSameSiteCookies(SECURE_ORIGIN, value);
+ var child = document.getElementById("if");
+ child.src = SECURE_ORIGIN + "/cookies/samesite/resources/iframe-navigate-report.html";
+
+ // the iframe nested inside if should post COOKIES to here.
+ var e = await wait_for_message("COOKIES");
+ // Not testing unspecified here as to not depend on the presence or
+ // absence of upcoming change of behavior.
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_lax", value, false);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_strict", value, false);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_none", value, true);
+ }, "SameSite cookies with intervening sandboxed iframe and navigation");
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/cookies/samesite/sandbox-iframe-subresource.https.html b/testing/web-platform/tests/cookies/samesite/sandbox-iframe-subresource.https.html
new file mode 100644
index 0000000000..417089ef57
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/sandbox-iframe-subresource.https.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/cookies/resources/cookie-helper.sub.js"></script>
+</head>
+<body onload="doTests()">
+ <iframe id="if" sandbox="allow-scripts">
+ </iframe>
+ <script>
+ function doTests() {
+ promise_test(async function(t) {
+ var value = "" + Math.random();
+ await resetSameSiteCookies(SECURE_ORIGIN, value);
+ var child = document.getElementById("if");
+ child.src = SECURE_ORIGIN + "/cookies/samesite/resources/iframe-subresource-report.html";
+
+ // the iframe nested inside if should post COOKIES to here.
+ var e = await wait_for_message("COOKIES");
+ // Not testing unspecified here as to not depend on the presence or
+ // absence of upcoming change of behavior.
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_lax", value, false);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_strict", value, false);
+ assert_cookie(SECURE_ORIGIN, e.data, "samesite_none", value, true);
+ }, "SameSite cookies with intervening sandboxed iframe and subresources");
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/cookies/samesite/setcookie-lax.https.html b/testing/web-platform/tests/cookies/samesite/setcookie-lax.https.html
new file mode 100644
index 0000000000..f2094af693
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/setcookie-lax.https.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ promise_test(async function(t) {
+ let w = window.open(SECURE_ORIGIN + "/cookies/samesite/resources/puppet.html");
+ await wait_for_message("READY", SECURE_ORIGIN);
+ let random = "" + Math.random();
+ w.postMessage({type: "set", value: random}, "*");
+ let e = await wait_for_message("set-complete", SECURE_ORIGIN)
+ assert_dom_cookie("samesite_strict", e.data.value, true);
+ assert_dom_cookie("samesite_lax", e.data.value, true);
+ assert_dom_cookie("samesite_none", e.data.value, true);
+ assert_dom_cookie("samesite_unspecified", e.data.value, true);
+ w.close();
+ }, "Same-site window should be able to set `SameSite=Lax` or `SameSite=Strict` cookies.");
+
+ promise_test(async function(t) {
+ let w = window.open(SECURE_CROSS_SITE_ORIGIN + "/cookies/samesite/resources/puppet.html");
+ await wait_for_message("READY", SECURE_CROSS_SITE_ORIGIN);
+ let random = "" + Math.random();
+ w.postMessage({type: "set", value: random}, "*");
+ let e = await wait_for_message("set-complete", SECURE_CROSS_SITE_ORIGIN);
+ assert_dom_cookie("samesite_strict", e.data.value, false);
+ assert_dom_cookie("samesite_lax", e.data.value, false);
+ assert_dom_cookie("samesite_none", e.data.value, true);
+ assert_dom_cookie("samesite_unspecified", e.data.value, false);
+ w.close();
+ }, "Cross-site window shouldn't be able to set `SameSite=Lax` or `SameSite=Strict` cookies.");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/setcookie-navigation.https.html b/testing/web-platform/tests/cookies/samesite/setcookie-navigation.https.html
new file mode 100644
index 0000000000..2dbc5526bc
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/setcookie-navigation.https.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ // Asserts that cookies are present or not present (according to `expectation`)
+ // in the cookie string `cookies` with the correct names and value.
+ function assert_cookies_present(cookies, value, expected_cookie_names, expectation) {
+ for (name of expected_cookie_names) {
+ let re = new RegExp("(?:^|; )" + name + "=" + value + "(?:$|;)");
+ let assertion = expectation ? assert_true : assert_false;
+ assertion(re.test(cookies), "`" + name + "=" + value + "` in cookies");
+ }
+ }
+
+ // Navigate from ORIGIN to |origin_to|, expecting the navigation to set SameSite
+ // cookies on |origin_to|.
+ function navigate_test(method, origin_to, title) {
+ promise_test(async function(t) {
+ // The cookies don't need to be cleared on each run because |value| is
+ // a new random value on each run, so on each run we are overwriting and
+ // checking for a cookie with a different random value.
+ let value = "" + Math.random();
+ let url_from = SECURE_ORIGIN + "/cookies/samesite/resources/navigate.html";
+ let url_to = origin_to + "/cookies/resources/setSameSite.py?" + value;
+ var w = window.open(url_from);
+ await wait_for_message('READY', SECURE_ORIGIN);
+ assert_equals(SECURE_ORIGIN, window.origin);
+ assert_equals(SECURE_ORIGIN, w.origin);
+ let command = (method === "POST") ? "post-form" : "navigate";
+ w.postMessage({ type: command, url: url_to }, "*");
+ let message = await wait_for_message('COOKIES_SET', origin_to);
+ let samesite_cookie_names = ['samesite_strict', 'samesite_lax', 'samesite_none', 'samesite_unspecified'];
+ assert_cookies_present(message.data.cookies, value, samesite_cookie_names, true);
+ w.close();
+ }, title);
+ }
+
+ // Opens a page on origin SECURE_ORIGIN containing an iframe on `iframe_origin_from`,
+ // then navigates that iframe to `iframe_origin_to`. Expects that navigation to set
+ // some subset of SameSite cookies.
+ function navigate_iframe_test(iframe_origin_from, iframe_origin_to, cross_site, title) {
+ promise_test(async function(t) {
+ // The cookies don't need to be cleared on each run because |value| is
+ // a new random value on each run, so on each run we are overwriting and
+ // checking for a cookie with a different random value.
+ let value = "" + Math.random();
+ let parent_url = SECURE_ORIGIN + "/cookies/samesite/resources/navigate-iframe.html";
+ let iframe_url_from = iframe_origin_from + "/cookies/samesite/resources/navigate.html";
+ let iframe_url_to = iframe_origin_to + "/cookies/resources/setSameSite.py?" + value;
+ var w = window.open(parent_url);
+ await wait_for_message('LOADED', SECURE_ORIGIN);
+ assert_equals(SECURE_ORIGIN, window.origin);
+ assert_equals(SECURE_ORIGIN, w.origin);
+ // Navigate the frame to its starting location.
+ w.postMessage({ type: 'initialize-iframe', url: iframe_url_from }, '*');
+ await wait_for_message('FRAME_READY', SECURE_ORIGIN);
+ // Have the frame navigate itself, possibly cross-site.
+ w.postMessage({ type: 'navigate-iframe', url: iframe_url_to }, '*');
+ let message = await wait_for_message('FRAME_COOKIES_SET', SECURE_ORIGIN);
+ // Check for the proper cookies.
+ let samesite_none_cookies = ['samesite_none'];
+ let samesite_cookies = ['samesite_strict', 'samesite_lax', 'samesite_unspecified'];
+ assert_cookies_present(message.data.cookies, value, samesite_none_cookies, true);
+ assert_cookies_present(message.data.cookies, value, samesite_cookies, !cross_site);
+ w.close();
+ }, title);
+ }
+
+ navigate_test("GET", SECURE_ORIGIN, "Same-site top-level navigation should be able to set SameSite=* cookies.");
+ navigate_test("GET", SECURE_CROSS_SITE_ORIGIN, "Cross-site top-level navigation should be able to set SameSite=* cookies.");
+ navigate_test("POST", SECURE_ORIGIN, "Same-site top-level POST should be able to set SameSite=* cookies.");
+ navigate_test("POST", SECURE_CROSS_SITE_ORIGIN, "Cross-site top-level POST should be able to set SameSite=* cookies.");
+
+ navigate_iframe_test(SECURE_ORIGIN, SECURE_ORIGIN, false, "Same-site to same-site iframe navigation should be able to set SameSite=* cookies.");
+ navigate_iframe_test(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN, true, "Cross-site to same-site iframe navigation should only be able to set SameSite=None cookies.");
+ navigate_iframe_test(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, true, "Same-site to cross-site-site iframe navigation should only be able to set SameSite=None cookies.");
+ navigate_iframe_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, true, "Cross-site to cross-site iframe navigation should only be able to set SameSite=None cookies.");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/window-open-reload.https.html b/testing/web-platform/tests/cookies/samesite/window-open-reload.https.html
new file mode 100644
index 0000000000..32076c7c97
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/window-open-reload.https.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ // This test opens a popup window to postToParent.py (on the specified
+ // origin). The popup sends a postMessage event back to its opener
+ // (i.e., here) with the cookies it received, which we verify against
+ // expectedStatus. Then, the test sends a message to the popup, telling it to
+ // reload itself via window.location.reload(). Again, the popup posts a
+ // message back here with the cookies it received. These cookies are verified
+ // against expectedStatusReload.
+ function create_test(origin, target, expectedStatus, expectedStatusReload, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var w = window.open(target + "/cookies/resources/postToParent.py");
+
+ var reloaded = false;
+ var msgHandler = e => {
+ try {
+ verifySameSiteCookieState(reloaded ? expectedStatusReload : expectedStatus, value, e.data, DomSameSiteStatus.SAME_SITE);
+ } catch (e) {
+ reject(e);
+ }
+
+ if (reloaded) {
+ window.removeEventListener("message", msgHandler);
+ w.close();
+ resolve("Popup received the cookie.");
+ } else {
+ reloaded = true;
+ w.postMessage("reload", "*");
+ }
+ };
+ window.addEventListener("message", msgHandler);
+
+ if (!w)
+ reject("Popup could not be opened (did you allow the test site in your popup blocker?).");
+ });
+ });
+ }, title);
+ }
+
+ // The reload status is always strictly same-site because this is a site-initiated reload, as opposed to a reload triggered by a user interface element.
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, SameSiteStatus.STRICT, "Reloaded same-host auxiliary navigations are strictly same-site.");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, SameSiteStatus.STRICT, "Reloaded subdomain auxiliary navigations are strictly same-site.");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.LAX, SameSiteStatus.STRICT, "Reloaded cross-site auxiliary navigations are strictly same-site");
+</script>
diff --git a/testing/web-platform/tests/cookies/samesite/window-open.https.html b/testing/web-platform/tests/cookies/samesite/window-open.https.html
new file mode 100644
index 0000000000..be4225046a
--- /dev/null
+++ b/testing/web-platform/tests/cookies/samesite/window-open.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<script>
+ function create_test(origin, target, expectedStatus, title) {
+ promise_test(t => {
+ var value = "" + Math.random();
+ return resetSameSiteCookies(origin, value)
+ .then(_ => {
+ return new Promise((resolve, reject) => {
+ var w = window.open(target + "/cookies/resources/postToParent.py");
+
+ var msgHandler = e => {
+ window.removeEventListener("message", msgHandler);
+ w.close();
+ try {
+ verifySameSiteCookieState(expectedStatus, value, e.data, DomSameSiteStatus.SAME_SITE);
+ resolve("Popup received the cookie.");
+ } catch (e) {
+ reject(e);
+ }
+ };
+ window.addEventListener("message", msgHandler);
+
+ if (!w)
+ reject("Popup could not be opened (did you allow the test site in your popup blocker?).");
+ });
+ });
+ }, title);
+ }
+
+ // No redirect:
+ create_test(SECURE_ORIGIN, SECURE_ORIGIN, SameSiteStatus.STRICT, "Same-host auxiliary navigations are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain auxiliary navigations are strictly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN, SameSiteStatus.LAX, "Cross-site auxiliary navigations are laxly same-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host auxiliary navigations are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host auxiliary navigations are strictly same-site");
+ create_test(SECURE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to same-host auxiliary navigations are laxly same-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to same-host:
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain auxiliary navigations are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain auxiliary navigations are strictly same-site");
+ create_test(SECURE_SUBDOMAIN_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_SUBDOMAIN_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to subdomain auxiliary navigations are laxly same-site");
+
+ // Redirect from {same-host,subdomain,cross-site} to cross-site:
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Same-host redirecting to cross-site auxiliary navigations are laxly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_SUBDOMAIN_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Subdomain redirecting to cross-site auxiliary navigations are laxly same-site");
+ create_test(SECURE_CROSS_SITE_ORIGIN, redirectTo(SECURE_CROSS_SITE_ORIGIN, SECURE_CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to cross-site auxiliary navigations are laxly same-site");
+</script>