summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/frame-src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/content-security-policy/frame-src
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/frame-src')
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-default.sub.html32
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-scheme.sub.html28
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-allowed.sub.html64
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-blocked.sub.html62
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-load.sub.html68
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-same-document-navigation.window.js45
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html35
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html.headers2
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document-meta.sub.html52
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html22
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html29
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html.headers4
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/frame-src-self-unique-origin.html49
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/support/frame.html2
-rw-r--r--testing/web-platform/tests/content-security-policy/frame-src/support/testharness-helper.sub.js5
16 files changed, 500 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-default.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-default.sub.html
new file mode 100644
index 0000000000..a9d40adee0
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-default.sub.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="frame-src 'none'; object-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>frame-src-about-blank-allowed-by-default</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS"]'></script>
+ <script src="../support/alertAssert.sub.js?alerts=[]"></script>
+
+ <p>These frames should not be blocked by Content-Security-Policy.
+ It&apos;s pointless to block about:blank iframes because
+ blocking a frame just results in displaying about:blank anyway!
+ </p>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("Fail");
+ });
+ </script>
+
+ <iframe src="about:blank"></iframe>
+ <object type="text/html" data="about:blank"></object>
+
+ <div id="log"></div>
+ <script>
+ log("PASS");
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-scheme.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-scheme.sub.html
new file mode 100644
index 0000000000..f5b62aaa2f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-about-blank-allowed-by-scheme.sub.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="frame-src about:; script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>frame-src-about-blank-allowed-by-scheme</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS"]'></script>
+ <script src="../support/alertAssert.sub.js?alerts=[]"></script>
+
+ <p>This frame should not be blocked by Content-Security-Policy.
+ </p>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("Fail");
+ });
+ </script>
+
+ <iframe src="about:blank"></iframe>
+ <div id="log"></div>
+ <script>
+ log("PASS");
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-allowed.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-allowed.sub.html
new file mode 100644
index 0000000000..8421a9cbfb
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-allowed.sub.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>frame-src-allowed</title>
+ <meta http-equiv="Content-Security-Policy" content="frame-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS IFrame %231 generated a load event."]'></script>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("Fail");
+ });
+
+ window.addEventListener("message", function(event) {
+ alert_assert(event.data);
+ }, false);
+
+ var t_alert = async_test('Expecting alerts: ["PASS"]');
+ var expected_alerts = ["PASS"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <p>
+ This iframe should be allowed.
+ </p>
+ <script>
+ window.wasPostTestScriptParsed = true;
+ var loads = 0;
+
+ function loadEvent() {
+ loads++;
+ log("PASS " + "IFrame #" + loads + " generated a load event.");
+ }
+
+ </script>
+</head>
+
+<body>
+ <iframe src="/content-security-policy/support/postmessage-pass.html" onload="loadEvent()"></iframe>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-blocked.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-blocked.sub.html
new file mode 100644
index 0000000000..a4957f8715
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-blocked.sub.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="frame-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>frame-src-blocked</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS IFrame %231 generated a load event.","violated-directive=frame-src"]'></script>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("violated-directive=" + e.violatedDirective);
+ });
+
+ window.addEventListener("message", function(event) {
+ alert_assert(event.data);
+ }, false);
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <p>
+ IFrames blocked by CSP should generate a 'load', not 'error' event, regardless of blocked state. This means they appear to be normal cross-origin loads, thereby not leaking URL information directly to JS.
+ </p>
+ <script>
+ window.wasPostTestScriptParsed = true;
+ var loads = 0;
+
+ function loadEvent() {
+ loads++;
+ log("PASS " + "IFrame #" + loads + " generated a load event.");
+ }
+
+ </script>
+</head>
+
+<body>
+ <iframe src="/content-security-policy/support/postmessage-fail.html" onload="loadEvent()" onerror="log('FAIL')"></iframe>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-load.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-load.sub.html
new file mode 100644
index 0000000000..956c79fbf0
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-load.sub.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="frame-src 'self' http://www1.{{host}}:{{ports[http][0]}}; script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>frame-src-cross-origin-load</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS IFrame %231 generated a load event.","PASS IFrame %232 generated a load event.","PASS IFrame %233 generated a load event.","violated-directive=frame-src"]'></script>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("violated-directive=" + e.violatedDirective);
+ });
+
+ window.addEventListener("message", function(event) {
+ alert_assert(event.data);
+ }, false);
+
+ var t_alert = async_test('Expecting alerts: ["PASS","PASS"]');
+ var expected_alerts = ["PASS", "PASS"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_alert.done();
+ });
+ }
+
+ </script>
+
+ <p>
+ IFrames blocked by CSP should generate a 'load', not 'error' event, regardless of blocked state. This means they appear to be normal cross-origin loads, thereby not leaking URL information directly to JS.
+ </p>
+ <script>
+ window.wasPostTestScriptParsed = true;
+ var loads = 0;
+
+ function loadEvent() {
+ loads++;
+ log("PASS " + "IFrame #" + loads + " generated a load event.");
+ }
+
+ </script>
+</head>
+
+<body>
+ <iframe src="../support/postmessage-pass.html" onload="loadEvent()"></iframe>
+ <iframe src="http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/support/postmessage-pass.html" onload="loadEvent()"></iframe>
+ <iframe src="http://www2.{{host}}:{{ports[http][0]}}/content-security-policy/support/postmessage-fail.html" onload="loadEvent()" onerror="log('FAIL')"></iframe>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-same-document-navigation.window.js b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-same-document-navigation.window.js
new file mode 100644
index 0000000000..4c77193541
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-cross-origin-same-document-navigation.window.js
@@ -0,0 +1,45 @@
+// META: script=/common/get-host-info.sub.js
+// META: script=/common/utils.js
+// META: script=/common/dispatcher/dispatcher.js
+
+// Regression test for https://crbug.com/1262203
+//
+// A cross-origin document initiates a same-document navigation. This navigation
+// is subject to CSP:frame-src 'none', but this doesn't apply, since it's a
+// same-document navigation. This test checks this doesn't lead to a crash.
+
+promise_test(async test => {
+ const child_token = token();
+ const child = new RemoteContext(child_token);
+ const iframe = document.createElement("iframe");
+ iframe.src = remoteExecutorUrl(child_token, {
+ host: get_host_info().REMOTE_HOST
+ });
+ document.body.appendChild(iframe);
+
+ // Install a promise waiting for a same-document navigation to happen in the
+ // child.
+ await child.execute_script(() => {
+ window.sameDocumentNavigation = new Promise(resolve => {
+ window.addEventListener("popstate", resolve);
+ });
+ });
+
+ // Append a new CSP, disallowing new iframe navigations.
+ const meta = document.createElement("meta");
+ meta.httpEquiv = "Content-Security-Policy";
+ meta.content = "frame-src 'none'";
+ document.head.appendChild(meta);
+
+ document.addEventListener(
+ "securitypolicyviolation",
+ test.unreached_func("same-document navigations aren't subject to CSP"));
+
+ // Create a same-document navigation, inititated cross-origin in the iframe.
+ // It must not be blocked by the CSP above.
+ iframe.src += "#foo";
+
+ // Make sure the navigation succeeded and was indeed a same-document one:
+ await child.execute_script(() => sameDocumentNavigation);
+ assert_equals(await child.execute_script(() => location.href), iframe.src);
+})
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html
new file mode 100644
index 0000000000..f5ac88b052
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="./support/testharness-helper.sub.js"></script>
+<body></body>
+<script>
+ function waitForViolation(el, policy, blocked_origin) {
+ return new Promise(resolve => {
+ el.addEventListener('securitypolicyviolation', e => {
+ if (e.originalPolicy == policy && (new URL(e.blockedURI)).origin == blocked_origin)
+ resolve(e);
+ });
+ });
+ }
+
+ async_test(t => {
+ var i = document.createElement("iframe");
+ var redirect = generateCrossOriginRedirectFrame();
+ i.src = redirect.url;
+
+ // Report-only policy should trigger a violation on the original request.
+ var original_report_only = waitForViolation(window, "frame-src http://foo.test", (new URL(i.src)).origin)
+ // Report-only policy should trigger a violation on the redirected request.
+ var redirect_report_only = waitForViolation(window, "frame-src http://foo.test", (new URL(redirect.target)).origin)
+ // Enforced policy should trigger a violation on the redirected request.
+ var redirect_enforced = waitForViolation(window, "frame-src 'self'", (new URL(redirect.target)).origin)
+
+ Promise.all([original_report_only, redirect_report_only, redirect_enforced]).then(t.step_func(_ => {
+ t.done();
+ }));
+
+ document.body.appendChild(i);
+ }, "Redirected iframe src should evaluate both enforced and report-only policies on both original request and when following redirect");
+</script>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html.headers b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html.headers
new file mode 100644
index 0000000000..338bea13b8
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-redirect.html.headers
@@ -0,0 +1,2 @@
+Content-Security-Policy: frame-src 'self'
+Content-Security-Policy-Report-Only: frame-src http://foo.test
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document-meta.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document-meta.sub.html
new file mode 100644
index 0000000000..f4122f3d35
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document-meta.sub.html
@@ -0,0 +1,52 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<html>
+<body></body>
+<script>
+ promise_test(async test => {
+ // 1. Load an iframe (not blocked).
+ let iframe = document.createElement("iframe");
+ {
+ iframe.name = "theiframe";
+ iframe.src =
+ "http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/frame-src/support/frame.html?0";
+ let iframeLoaded = new Promise(resolve => { iframe.onload = resolve });
+ document.body.appendChild(iframe);
+ await iframeLoaded;
+ }
+
+ // 2. Start blocking iframes using CSP frame-src 'none'.
+ {
+ let meta = document.createElement('meta');
+ meta.httpEquiv = "Content-Security-Policy";
+ meta.content = "frame-src 'none'";
+ document.getElementsByTagName('head')[0].appendChild(meta);
+ }
+
+ // 3. Blocked same-document navigation using iframe.src.
+ {
+ let violation = new Promise(resolve => {
+ window.addEventListener('securitypolicyviolation', () => resolve());
+ });
+ iframe.src =
+ "http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/frame-src/support/frame.html?1";
+ await violation;
+ }
+
+ // 4. Blocked same-document navigation using window.open.
+ {
+ let violation = new Promise(resolve => {
+ window.addEventListener('securitypolicyviolation', resolve);
+ });
+ window.open(
+ "http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/frame-src/support/frame.html?2",
+ "theiframe");
+ await violation;
+ }
+
+ // 5. Regression test for https://crbug.com/1018385. The browser should
+ // not crash while displaying the error page.
+ await new Promise(resolve => window.setTimeout(resolve, 1000));
+ }, "Same-document navigations in an iframe blocked by CSP frame-src dynamically using the <meta> tag");
+</script>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html
new file mode 100644
index 0000000000..9868f92955
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html
@@ -0,0 +1,22 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<html>
+<body></body>
+<script>
+ let crossOriginUrl =
+ "http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/frame-src/support/frame.html";
+
+ promise_test(async test => {
+ let iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+
+ for(let hash of ["#0", "#1"]) {
+ let violation = new Promise(resolve => {
+ window.addEventListener('securitypolicyviolation', resolve);
+ });
+ iframe.src = crossOriginUrl + hash;
+ await violation;
+ }
+ }, "Same-document navigation in an iframe blocked by CSP frame-src");
+</script>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html.headers b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html.headers
new file mode 100644
index 0000000000..6502444407
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-same-document.sub.html.headers
@@ -0,0 +1 @@
+Content-Security-Policy: frame-src 'none'
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html
new file mode 100644
index 0000000000..419a14458b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Frame-src: 'self' matches even if the parent's origin is unique.</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script>
+ var t = async_test('SubframeLoaded');
+
+ window.addEventListener('securitypolicyviolation', t.step_func(function(e) {
+ if (e.violatedDirective === "frame-src") {
+ assert_unreached('unexpected securitypolicyviolation');
+ t.done();
+ }
+ }));
+
+ window.addEventListener("message", t.step_func(function(event) {
+ assert_equals(event.data, "PASS", 'unexpected message: ' + event.data);
+ t.done();
+ }));
+
+ f = document.createElement("iframe");
+ f.src = "/content-security-policy/support/postmessage-pass.html";
+ document.body.appendChild(f);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html.headers b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html.headers
new file mode 100644
index 0000000000..ec9e8deb59
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-sandboxed-allowed.html.headers
@@ -0,0 +1,4 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Pragma: no-cache
+Content-Security-Policy: frame-src 'self'; sandbox allow-scripts
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/frame-src-self-unique-origin.html b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-self-unique-origin.html
new file mode 100644
index 0000000000..3d04a08ad7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/frame-src-self-unique-origin.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>frame-src-self-unique-origin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+ <p>
+ The origin of an URL is called "unique" when it is considered to be
+ different from every origin, including itself. The origin of a
+ data-url is unique. When the current origin is unique, the CSP source
+ 'self' must not match any URL.
+ </p>
+ <script>
+ var iframe = document.createElement("iframe");
+ iframe.src = encodeURI(`data:text/html,
+ <script>
+ /* Add the CSP: frame-src: 'self'. */
+ var meta = document.createElement('meta');
+ meta.httpEquiv = 'Content-Security-Policy';
+ meta.content = "frame-src 'self'";
+ document.getElementsByTagName('head')[0].appendChild(meta);
+
+ /* Notify the parent the iframe has been blocked. */
+ window.addEventListener('securitypolicyviolation', e => {
+ if (e.originalPolicy == "frame-src 'self'")
+ window.parent.postMessage('Test PASS', '*');
+ });
+ </scr`+`ipt>
+
+ This iframe should be blocked by CSP:
+ <iframe src='data:text/html,blocked_iframe'></iframe>
+ `);
+ if (window.async_test) {
+ async_test(t => {
+ window.addEventListener("message", e => {
+ if (e.data == "Test PASS")
+ t.done();
+ });
+ }, "Iframe's url must not match with 'self'. It must be blocked.");
+ }
+ document.body.appendChild(iframe);
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/support/frame.html b/testing/web-platform/tests/content-security-policy/frame-src/support/frame.html
new file mode 100644
index 0000000000..50be429587
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/support/frame.html
@@ -0,0 +1,2 @@
+<!doctype html>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/frame-src/support/testharness-helper.sub.js b/testing/web-platform/tests/content-security-policy/frame-src/support/testharness-helper.sub.js
new file mode 100644
index 0000000000..b9e9a6c856
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/frame-src/support/testharness-helper.sub.js
@@ -0,0 +1,5 @@
+function generateCrossOriginRedirectFrame() {
+ var target = "http://{{domains[天気の良い日]}}:" + document.location.port + "/content-security-policy/frame-src/support/frame.html";
+ var url = "/common/redirect.py?location=" + encodeURIComponent(target);
+ return { url: url, target: target };
+}