summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/frame-ancestors
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/content-security-policy/frame-ancestors
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/frame-ancestors')
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-from-serviceworker.https.html46
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-star-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html17
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-star-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-self-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-star-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-allow.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-none-block.html23
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-overrides-xfo.html39
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-sandbox-same-origin-self.html17
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-allow.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-sameorigin.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-allow.sub.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-block.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/report-blocked-frame.sub.html13
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/report-only-frame.sub.html13
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html6
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html6
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html9
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html.sub.headers3
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-test.sub.js147
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html9
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html.sub.headers2
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-ancestors/support/service-worker.js10
45 files changed, 774 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-from-serviceworker.https.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-from-serviceworker.https.html
new file mode 100644
index 0000000000..a0656a97a7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-from-serviceworker.https.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+</head>
+<body>
+ <script>
+ var t = async_test("A 'frame-ancestors' CSP directive set from a serviceworker response with a value 'none' should block rendering.");
+
+ // Register service worker.
+ var worker = 'support/service-worker.js';
+ var scope = 'support/service-worker/';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(registration => wait_for_state(t, registration.installing, 'activated'))
+ .then(() => {
+ // Load iframe.
+ var iframe = document.createElement("iframe");
+ let timer;
+ function pollForLoadCompletion() {
+ timer = t.step_timeout(() => iframeMayBeLoaded({isPoll: true}), 10);
+ }
+ function iframeMayBeLoaded({isPoll}) {
+ var failed = false;
+ clearTimeout(timer);
+ try {
+ let href = iframe.contentWindow.location.href;
+ if (isPoll && (href === "about:blank" || iframe.contentDocument.readyState !== "complete")) {
+ pollForLoadCompletion();
+ return;
+ }
+ failed = true;
+ } catch (ex) {}
+ t.step_func_done(() => assert_false(failed, "The IFrame should have been blocked. It wasn't."))();
+ };
+ iframe.addEventListener("load", () => iframeMayBeLoaded({isPoll: false}));
+ iframe.addEventListener("error", () => iframeMayBeLoaded({isPoll: false}));
+ iframe.src = "/content-security-policy/frame-ancestors/support/service-worker/frame-ancestors-none.html";
+ document.body.appendChild(iframe);
+ pollForLoadCompletion();
+ });
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block.html
new file mode 100644
index 0000000000..674deb655a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-none-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'none' should block rendering in nested frames.");
+
+ testNestedIFrame("'none'", CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block.html
new file mode 100644
index 0000000000..85b7f0efdc
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-self-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'same' should block render in same-origin nested frames.");
+
+ testNestedIFrame("'self'", CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-star-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-star-allow.html
new file mode 100644
index 0000000000..7f5a867de9
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-star-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value '*' should render in nested frames.");
+
+ testNestedIFrame("*", CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-allow.html
new file mode 100644
index 0000000000..99ab0718e8
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(SAMEORIGIN_ORIGIN + " " + CROSSORIGIN_ORIGIN, CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block.html
new file mode 100644
index 0000000000..9bcf63735e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-cross-url-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(CROSSORIGIN_ORIGIN, CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block.html
new file mode 100644
index 0000000000..1cdd540149
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-none-block.html
@@ -0,0 +1,16 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'none' should block rendering in nested frames.");
+
+ testNestedIFrame("'none'", SAME_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block.html
new file mode 100644
index 0000000000..da97339711
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-self-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'same' should block render in same-origin nested frames.");
+
+ testNestedIFrame("'self'", SAME_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html
new file mode 100644
index 0000000000..3658fb6502
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-star-allow.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value '*' should render in nested frames.");
+
+ // Note that we can't distinguish blocked URLs from allowed cross-origin URLs due to the same-origin policy. This test passes if no console message declares that the frame was blocked.
+ testNestedIFrame("*", SAME_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html
new file mode 100644
index 0000000000..1f1ffb9f89
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-allow.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ // Note that we can't distinguish blocked URLs from allowed cross-origin URLs due to the same-origin policy. This test passes if no console message declares that the frame was blocked.
+ testNestedIFrame(SAMEORIGIN_ORIGIN + " " + CROSSORIGIN_ORIGIN, SAME_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block.html
new file mode 100644
index 0000000000..62dd1c1ef6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-same-url-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(CROSSORIGIN_ORIGIN, SAME_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html
new file mode 100644
index 0000000000..d7c83ae2f5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-cross-in-sandboxed-cross-url-block.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should compare against each frame's origin rather than URL, " +
+ "so a nested frame with a sandboxed parent frame should be blocked due to the parent having a unique origin.");
+
+ testNestedSandboxedIFrame(SAMEORIGIN_ORIGIN + " " + CROSSORIGIN_ORIGIN, CROSS_ORIGIN, CROSS_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block.html
new file mode 100644
index 0000000000..f01c6d766f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-none-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'none' should block rendering in nested frames.");
+
+ testNestedIFrame("'none'", CROSS_ORIGIN, SAME_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block.html
new file mode 100644
index 0000000000..bae5992e86
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-self-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'same' should block render in same-origin nested frames.");
+
+ testNestedIFrame("'self'", CROSS_ORIGIN, SAME_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-star-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-star-allow.html
new file mode 100644
index 0000000000..85d66f660a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-star-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value '*' should render in nested frames.");
+
+ testNestedIFrame("*", CROSS_ORIGIN, SAME_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-allow.html
new file mode 100644
index 0000000000..dff041be9a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(SAMEORIGIN_ORIGIN + " " + CROSSORIGIN_ORIGIN, CROSS_ORIGIN, SAME_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block.html
new file mode 100644
index 0000000000..5d2fc57ac1
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-cross-url-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(SAMEORIGIN_ORIGIN, CROSS_ORIGIN, SAME_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block.html
new file mode 100644
index 0000000000..234cca82c8
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-none-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'none' should block rendering in nested frames.");
+
+ testNestedIFrame("'none'", SAME_ORIGIN, SAME_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-self-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-self-allow.html
new file mode 100644
index 0000000000..747c563696
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-self-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'same' should block render in same-origin nested frames.");
+
+ testNestedIFrame("'self'", SAME_ORIGIN, SAME_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-star-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-star-allow.html
new file mode 100644
index 0000000000..d7eaf73fd6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-star-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value '*' should render in nested frames.");
+
+ testNestedIFrame("*", SAME_ORIGIN, SAME_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-allow.html
new file mode 100644
index 0000000000..432c25f0d2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-allow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(SAMEORIGIN_ORIGIN, SAME_ORIGIN, SAME_ORIGIN, EXPECT_LOAD);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block.html
new file mode 100644
index 0000000000..c02091bf4f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-nested-same-in-same-url-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL value should block or allow rendering in nested frames as appropriate.");
+
+ testNestedIFrame(CROSSORIGIN_ORIGIN, SAME_ORIGIN, SAME_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-none-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-none-block.html
new file mode 100644
index 0000000000..f494468e37
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-none-block.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ async_test(t => {
+ window.addEventListener('securitypolicyviolation', t.step_func(function(e) {
+ if (e.violatedDirective === 'frame-ancestors')
+ assert_unreached('No securitypolicyviolation event shoud be raised in the parent.');
+ }));
+ t.step_timeout(function() { t.done(); }, 2000);
+ });
+
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'none' should block rendering.");
+
+ sameOriginFrameShouldBeBlocked("'none'");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-overrides-xfo.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-overrides-xfo.html
new file mode 100644
index 0000000000..9e6d3d729c
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-overrides-xfo.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <script>
+ async_test(function (t) {
+ var i = document.createElement('iframe');
+ i.src = "support/frame-ancestors-and-x-frame-options.sub.html?policy='self'&xfo=DENY";
+ i.onload = t.step_func_done(function () {
+ assert_equals(i.contentWindow.origin, window.origin, "The same-origin page loaded.");
+ });
+ document.body.appendChild(i);
+ }, "A 'frame-ancestors' CSP directive overrides an 'x-frame-options' header which would block the page.");
+
+ async_test(function (t) {
+ var i = document.createElement('iframe');
+ i.src = "support/frame-ancestors-and-x-frame-options.sub.html?policy=other-origin.com&xfo=SAMEORIGIN";
+ checkDone = t.step_func(function() {
+ clearTimeout(timer);
+ try {
+ if (i.contentWindow.location.href === "about:blank" ||
+ (i.contentDocument && i.contentDocument.readyState !== "complete")) {
+ timer = t.step_timeout(checkDone, 10);
+ return;
+ }
+ } catch(e) {}
+ assert_equals(i.contentDocument, null);
+ t.done();
+ });
+ i.onload = checkDone;
+ let timer = t.step_timeout(checkDone, 10);
+ document.body.appendChild(i);
+ }, "A 'frame-ancestors' CSP directive overrides an 'x-frame-options' header which would allow the page.");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-sandbox-same-origin-self.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-sandbox-same-origin-self.html
new file mode 100644
index 0000000000..4a2a19698d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-sandbox-same-origin-self.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a 'self' value " +
+ "should compare the child URL (self) against each parent's origin's URL" +
+ " rather then URL. When the ancestors are sandboxed, they never match.");
+
+ testNestedSandboxedIFrame('self', SAME_ORIGIN, SAME_ORIGIN, EXPECT_BLOCK);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-allow.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-allow.html
new file mode 100644
index 0000000000..a8a295dfc4
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-allow.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'self' should allow rendering.");
+
+ sameOriginFrameShouldBeAllowed("'self'");
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-block.html
new file mode 100644
index 0000000000..438f2b8eb2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-self-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a value 'self' should block rendering.");
+
+ crossOriginFrameShouldBeBlocked("'self'");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin.html
new file mode 100644
index 0000000000..09ee28bbea
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-crossorigin.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with '*' should allow rendering.");
+
+ // Note that we can't distinguish blocked URLs from allowed cross-origin URLs due to the same-origin policy. This test passes if no console message declares that the frame was blocked.
+ crossOriginFrameShouldBeBlocked("*");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-sameorigin.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-sameorigin.html
new file mode 100644
index 0000000000..62bbe45b25
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-star-allow-sameorigin.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with '*' should allow rendering.");
+
+ sameOriginFrameShouldBeAllowed("*");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-allow.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-allow.sub.html
new file mode 100644
index 0000000000..f4f42e475f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-allow.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL matching this origin should allow rendering.");
+
+ sameOriginFrameShouldBeAllowed('{{location[scheme]}}://{{location[host]}}');
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-block.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-block.html
new file mode 100644
index 0000000000..c320370be5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/frame-ancestors-url-block.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/frame-ancestors-test.sub.js"></script>
+</head>
+<body>
+ <script>
+ test = async_test("A 'frame-ancestors' CSP directive with a URL which doesn't match this origin should be blocked.");
+
+ crossOriginFrameShouldBeBlocked("http://example.com/");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/report-blocked-frame.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/report-blocked-frame.sub.html
new file mode 100644
index 0000000000..a7532b7cf2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/report-blocked-frame.sub.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<meta name="timeout" content="long">
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Blocked frames are reported correctly</title>
+</head>
+<body>
+ <iframe src="support/content-security-policy.sub.html?policy=report-uri%20/reporting/resources/report.py%3Fop=put%26reportID={{$id:uuid()}}%3B%20frame-ancestors%20'none'"></iframe>
+ <script async defer src="../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors%20'none'&reportID={{$id}}"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/report-only-frame.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/report-only-frame.sub.html
new file mode 100644
index 0000000000..55289db6d6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/report-only-frame.sub.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<meta name="timeout" content="long">
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Blocked frames are reported correctly</title>
+</head>
+<body>
+ <iframe src="support/content-security-policy-report-only.sub.html?policy=report-uri%20/reporting/resources/report.py%3Fop=put%26reportID={{$id:uuid()}}%3B%20frame-ancestors%20'none'"></iframe>
+ <script async defer src="../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors%20'none'&reportID={{$id}}"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html
new file mode 100644
index 0000000000..c8317b91cf
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>This is an IFrame sending a Content-Security-Policy-Report-Only header containing "{{GET[policy]}}".</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html.sub.headers
new file mode 100644
index 0000000000..ccb142e569
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy-report-only.sub.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy-Report-Only: {{GET[policy]}}
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html
new file mode 100644
index 0000000000..2182f4a3d2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>This is an IFrame sending a Content Security Policy header containing "{{GET[policy]}}".</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html.sub.headers
new file mode 100644
index 0000000000..322c99d518
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/content-security-policy.sub.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: {{GET[policy]}}
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html
new file mode 100644
index 0000000000..e22fea3ccd
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>This is an IFrame sending a Content Security Policy header containing "frame-ancestors {{GET[policy]}}" and "X-Frame-Options: {{GET[xfo]}}".</p>
+ <script>
+ // This is an IFrame sending a Content Security Policy header containing "frame-ancestors {{GET[policy]}}" and "X-Frame-Options: {{GET[xfo]}}".
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html.sub.headers
new file mode 100644
index 0000000000..636e0facde
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-and-x-frame-options.sub.html.sub.headers
@@ -0,0 +1,3 @@
+Content-Type: text/html; charset=UTF-8
+Content-Security-Policy: frame-ancestors {{GET[policy]}}
+X-Frame-Options: {{GET[xfo]}}
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-test.sub.js b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-test.sub.js
new file mode 100644
index 0000000000..6e816e89b3
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors-test.sub.js
@@ -0,0 +1,147 @@
+var SAME_ORIGIN = true;
+var CROSS_ORIGIN = false;
+
+var EXPECT_BLOCK = true;
+var EXPECT_LOAD = false;
+
+var SAMEORIGIN_ORIGIN = "{{location[scheme]}}://{{location[host]}}";
+var CROSSORIGIN_ORIGIN = "http://{{domains[www1]}}:{{ports[http][1]}}";
+
+var test;
+
+function endTest(failed, message) {
+ if (typeof test === 'undefined') return;
+
+ if (failed) {
+ test.step(function() {
+ assert_unreached(message);
+ test.done();
+ });
+ }
+ else test.done({message: message});
+}
+
+window.addEventListener("message", function (e) {
+ if (window.parent != window)
+ window.parent.postMessage(e.data, "*");
+ else
+ if (e.data.type === 'test_result')
+ endTest(e.data.failed, "Inner IFrame msg: " + e.data.message);
+});
+
+function injectNestedIframe(policy, parent, child, expectation, isSandboxed) {
+ var iframe = document.createElement("iframe");
+
+ var url = "/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html"
+ + "?policy=" + policy
+ + "&parent=" + parent
+ + "&child=" + child
+ + "&expectation=" + expectation;
+ url = (parent == "same" ? SAMEORIGIN_ORIGIN : CROSSORIGIN_ORIGIN) + url;
+
+ iframe.src = url;
+
+ if (isSandboxed)
+ iframe.sandbox = 'allow-scripts';
+
+ document.body.appendChild(iframe);
+}
+
+let timer;
+function pollForLoadCompletion({iframe, expectBlock}) {
+ let fn = iframeLoaded({expectBlock, isPoll: true});
+ timer = test.step_timeout(() => fn({target: iframe}), 10);
+}
+
+function injectIFrame(policy, sameOrigin, expectBlock) {
+ var iframe = document.createElement("iframe");
+ iframe.addEventListener("load", iframeLoaded({expectBlock, isPoll: false}));
+ iframe.addEventListener("error", iframeLoaded({expectBlock, isPoll: false}));
+
+ var url = "/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html?policy=" + policy;
+ if (sameOrigin)
+ url = SAMEORIGIN_ORIGIN + url;
+ else
+ url = CROSSORIGIN_ORIGIN + url;
+
+ iframe.src = url;
+ document.body.appendChild(iframe);
+ pollForLoadCompletion({iframe, expectBlock});
+}
+
+function iframeLoaded({isPoll, expectBlock}) {
+ return function(ev) {
+ clearTimeout(timer);
+ var failed = true;
+ var message = "";
+ try {
+ let url = ev.target.contentWindow.location.href;
+ if (isPoll && (url === "about:blank" || ev.target.contentDocument.readyState !== "complete")) {
+ pollForLoadCompletion({iframe: ev.target, expectBlock});
+ return;
+ }
+ if (expectBlock) {
+ message = "The IFrame should have been blocked (or cross-origin). It wasn't.";
+ failed = true;
+ } else {
+ message = "The IFrame should not have been blocked. It wasn't.";
+ failed = false;
+ }
+ } catch (ex) {
+ if (expectBlock) {
+ message = "The IFrame should have been blocked (or cross-origin). It was.";
+ failed = false;
+ } else {
+ message = "The IFrame should not have been blocked. It was.";
+ failed = true;
+ }
+ }
+ if (window.parent != window)
+ window.parent.postMessage({type: 'test_result', failed: failed, message: message}, '*');
+ else
+ endTest(failed, message);
+ };
+}
+
+function originFrameShouldBe(child, expectation, policy) {
+ if (child == "cross" && expectation == "blocked") crossOriginFrameShouldBeBlocked(policy);
+ if (child == "same" && expectation == "blocked") sameOriginFrameShouldBeBlocked(policy);
+ if (child == "cross" && expectation == "allowed") crossOriginFrameShouldBeAllowed(policy);
+ if (child == "same" && expectation == "allowed") sameOriginFrameShouldBeAllowed(policy);
+}
+
+function crossOriginFrameShouldBeBlocked(policy) {
+ window.onload = function () {
+ injectIFrame(policy, CROSS_ORIGIN, EXPECT_BLOCK);
+ };
+}
+
+function crossOriginFrameShouldBeAllowed(policy) {
+ window.onload = function () {
+ injectIFrame(policy, CROSS_ORIGIN, EXPECT_LOAD);
+ };
+}
+
+function sameOriginFrameShouldBeBlocked(policy) {
+ window.onload = function () {
+ injectIFrame(policy, SAME_ORIGIN, EXPECT_BLOCK);
+ };
+}
+
+function sameOriginFrameShouldBeAllowed(policy) {
+ window.onload = function () {
+ injectIFrame(policy, SAME_ORIGIN, EXPECT_LOAD);
+ };
+}
+
+function testNestedIFrame(policy, parent, child, expectation) {
+ window.onload = function () {
+ injectNestedIframe(policy, parent == SAME_ORIGIN ? "same" : "cross", child == SAME_ORIGIN ? "same" : "cross", expectation == EXPECT_LOAD ? "allowed" : "blocked", false /* isSandboxed */);
+ };
+}
+
+function testNestedSandboxedIFrame(policy, parent, child, expectation) {
+ window.onload = function () {
+ injectNestedIframe(policy, parent == SAME_ORIGIN ? "same" : "cross", child == SAME_ORIGIN ? "same" : "cross", expectation == EXPECT_LOAD ? "allowed" : "blocked", true /* isSandboxed */);
+ };
+}
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html
new file mode 100644
index 0000000000..de65277343
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>This is an IFrame sending a Content Security Policy header containing "frame-ancestors {{GET[policy]}}".</p>
+ <script>
+ // This is an IFrame sending a Content Security Policy header containing "frame-ancestors {{GET[policy]}}"
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html.sub.headers
new file mode 100644
index 0000000000..9369a4101f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-ancestors.sub.html.sub.headers
@@ -0,0 +1,2 @@
+Content-Type: text/html; charset=UTF-8
+Content-Security-Policy: frame-ancestors {{GET[policy]}}
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html
new file mode 100644
index 0000000000..993b6bfd4b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='/content-security-policy/frame-ancestors/support/frame-ancestors-test.sub.js'></script>
+
+ <span id="escape">{{GET[policy]}}</span>
+
+ <script>
+ test = async_test("Testing a {{GET[child]}}-origin child with a policy of {{GET[policy]}} nested in a {{GET[parent]}}-origin parent");
+ const policy = document.getElementById("escape").textContent;
+ originFrameShouldBe("{{GET[child]}}", "{{GET[expectation]}}", policy);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html.sub.headers
new file mode 100644
index 0000000000..e853d6cee5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/frame-in-frame.sub.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=UTF-8
diff --git a/testing/web-platform/tests/content-security-policy/frame-ancestors/support/service-worker.js b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/service-worker.js
new file mode 100644
index 0000000000..ebced90f50
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-ancestors/support/service-worker.js
@@ -0,0 +1,10 @@
+self.onfetch = e => {
+ e.respondWith(function() {
+ return new Promise((resolve) => {
+ var headers = new Headers;
+ headers.append("Content-Security-Policy", "frame-ancestors 'none'");
+ var response = new Response("", { "headers" : headers, "status": 200, "statusText" : "OK" });
+ resolve(response);
+ });
+ }());
+};