CSP: initial blank page inherits 'self'.

Content-Security-Policy: The CSP source 'self' is usually the origin of
the current document. Immediately after an new window or new frame is
created, there are no current document. In this case, the origin used is
the one of the opener (in case of a new window) or the parent (in case of a
new iframe).

For you intention: The frame's CSP are already the one of its opener when
there are still no committed document. It makes sense to do the same
with 'self'.

Several web platform tests are added.

Bug: 807206
Change-Id: I2acf66d9b6d63d4efb14370a4d0ff2206c943aeb
Reviewed-on: https://chromium-review.googlesource.com/895589
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534017}
diff --git a/content-security-policy/form-action/form-action-src-allowed-target-blank.sub.html b/content-security-policy/form-action/form-action-src-allowed-target-blank.sub.html
new file mode 100644
index 0000000..46747b7
--- /dev/null
+++ b/content-security-policy/form-action/form-action-src-allowed-target-blank.sub.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>form-action-src-redirect-allowed-target-blank</title>
+  <meta http-equiv="Content-Security-Policy" content="form-action 'self'">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    function OnDocumentLoaded() {
+      let test = async_test("form submission targetting _blank allowed after a redirect");
+      window.addEventListener("message", function(event) {
+        if (event.data == "DocumentNotBlocked") {
+          event.source.close();
+          test.done();
+        }
+      });
+
+      let form = document.getElementById("form");
+      form.action =
+        "/content-security-policy/form-action/support/post-message-to-opener.sub.html";
+
+      let submit = document.getElementById("submit");
+      submit.click();
+    }
+  </script>
+</head>
+<body onload="OnDocumentLoaded();">
+  <form id="form" method="GET" target="_blank">
+    <input type="hidden" name="message" value="DocumentNotBlocked">
+    <input type="submit" id="submit">
+  </form>
+</body>
+</html>
+
diff --git a/content-security-policy/form-action/form-action-src-allowed-target-frame.sub.html b/content-security-policy/form-action/form-action-src-allowed-target-frame.sub.html
new file mode 100644
index 0000000..81921d3
--- /dev/null
+++ b/content-security-policy/form-action/form-action-src-allowed-target-frame.sub.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>form-action-src-allowed-target-frame</title>
+  <meta http-equiv="Content-Security-Policy" content="form-action 'self'">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    function OnDocumentLoaded() {
+      let test = async_test("form submission targetting a frame allowed");
+      window.addEventListener("message", function(event) {
+        if (event.data == "DocumentNotBlocked") {
+          test.done();
+        }
+      });
+
+      let form = document.getElementById("form");
+      form.action =
+        "/content-security-policy/form-action/support/post-message-to-parent.sub.html";
+
+      let submit = document.getElementById("submit");
+      submit.click();
+    }
+  </script>
+</head>
+<body onload="OnDocumentLoaded();">
+  <form id="form" method="GET" target="frame">
+    <input type="hidden" name="message" value="DocumentNotBlocked">
+    <input type="submit" id="submit">
+  </form>
+  <iframe name="frame"></iframe>
+</body>
+</html>
+
diff --git a/content-security-policy/form-action/form-action-src-redirect-allowed-target-blank.sub.html b/content-security-policy/form-action/form-action-src-redirect-allowed-target-blank.sub.html
new file mode 100644
index 0000000..41c68b6
--- /dev/null
+++ b/content-security-policy/form-action/form-action-src-redirect-allowed-target-blank.sub.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>form-action-src-redirect-allowed-target-blank</title>
+  <meta http-equiv="Content-Security-Policy" content="form-action 'self'">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    function OnDocumentLoaded() {
+      let test = async_test("form submission targetting _blank allowed after a redirect");
+      window.addEventListener("message", function(event) {
+        if (event.data == "DocumentNotBlocked") {
+          event.source.close();
+          test.done();
+        }
+      });
+
+      let form = document.getElementById("form");
+      let final_url = "/content-security-policy/form-action/support/post-message-to-opener.sub.html?message=DocumentNotBlocked";
+      let redirect_url = "/common/redirect.py?location=";
+      form.action = redirect_url + encodeURIComponent(final_url);
+
+      let submit = document.getElementById("submit");
+      submit.click();
+    }
+  </script>
+</head>
+<body onload="OnDocumentLoaded();">
+  <form id="form" method="POST" target="_blank">
+    <input type="submit" id="submit">
+  </form>
+</body>
+</html>
+
diff --git a/content-security-policy/form-action/form-action-src-redirect-allowed-target-frame.sub.html b/content-security-policy/form-action/form-action-src-redirect-allowed-target-frame.sub.html
new file mode 100644
index 0000000..6afd445
--- /dev/null
+++ b/content-security-policy/form-action/form-action-src-redirect-allowed-target-frame.sub.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>form-action-src-redirect-allowed-target-frame</title>
+  <meta http-equiv="Content-Security-Policy" content="form-action 'self'">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    function OnDocumentLoaded() {
+      let test = async_test("form submission targetting a frame allowed after a redirect");
+      window.addEventListener("message", function(event) {
+        if (event.data == "DocumentNotBlocked") {
+          test.done();
+        }
+      });
+
+      let form = document.getElementById("form");
+      let final_url = "/content-security-policy/form-action/support/post-message-to-parent.sub.html?message=DocumentNotBlocked";
+      let redirect_url = "/common/redirect.py?location=";
+      form.action = redirect_url + encodeURIComponent(final_url);
+
+      let submit = document.getElementById("submit");
+      submit.click();
+    }
+  </script>
+</head>
+<body onload="OnDocumentLoaded();">
+  <form id="form" method="POST" target="frame">
+    <input type="submit" id="submit">
+  </form>
+  <iframe name="frame"></iframe>
+</body>
+</html>
+
diff --git a/content-security-policy/form-action/support/post-message-to-opener.sub.html b/content-security-policy/form-action/support/post-message-to-opener.sub.html
new file mode 100644
index 0000000..0348139
--- /dev/null
+++ b/content-security-policy/form-action/support/post-message-to-opener.sub.html
@@ -0,0 +1,3 @@
+<script>
+  opener.postMessage("{{GET[message]}}", "*");
+</script>
diff --git a/content-security-policy/form-action/support/post-message-to-parent.sub.html b/content-security-policy/form-action/support/post-message-to-parent.sub.html
new file mode 100644
index 0000000..63e464b
--- /dev/null
+++ b/content-security-policy/form-action/support/post-message-to-parent.sub.html
@@ -0,0 +1,3 @@
+<script>
+  parent.postMessage("{{GET[message]}}", "*");
+</script>