Commit 6b230213 authored by Domenic Denicola's avatar Domenic Denicola Committed by Commit Bot

Origin isolation: test redirects

Fixed: 1127960
Change-Id: I23af107492b2db6d51d05c804398823c1fdef606
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2426995
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Reviewed-by: default avatarJames MacLean <wjmaclean@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811873}
parent a8759f90
<!DOCTYPE html>
<meta charset="utf-8">
<title>Parent is not isolated, child is reached via a redirect response with no header, child final response does have the header</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script type="module">
import {
insertIframe,
testDifferentAgentClusters,
testGetter
} from "../resources/helpers.mjs";
promise_setup(async () => {
await insertIframe("{{hosts[][www]}}", "?1", { redirectFirst: true });
});
// Since they're different-origin, the child's isolation request is respected,
// so the parent ends up in the site-keyed agent cluster and the child in the
// origin-keyed one.
testDifferentAgentClusters([self, 0]);
testGetter(self, false, "parent");
testGetter(0, true, "child");
</script>
...@@ -6,11 +6,15 @@ ...@@ -6,11 +6,15 @@
* @param {string} host - The host used to calculate the iframe's src="" * @param {string} host - The host used to calculate the iframe's src=""
* @param {string=} header - The value of the Origin-Isolation header that the * @param {string=} header - The value of the Origin-Isolation header that the
* iframe will set. Omit this to set no header. * iframe will set. Omit this to set no header.
* @param {object=} options - Rarely-used options.
* @param {boolean=} options.redirectFirst - Whether to do a 302 redirect first
* before arriving at the isolated page. The redirecting page will not set
* the Origin-Isolation header.
* @returns {HTMLIFrameElement} The created iframe element * @returns {HTMLIFrameElement} The created iframe element
*/ */
export async function insertIframe(host, header) { export async function insertIframe(host, header, { redirectFirst = false } = {}) {
const iframe = document.createElement("iframe"); const iframe = document.createElement("iframe");
const navigatePromise = navigateIframe(iframe, host, header); const navigatePromise = navigateIframe(iframe, host, header, { redirectFirst });
document.body.append(iframe); document.body.append(iframe);
await navigatePromise; await navigatePromise;
await setBothDocumentDomains(iframe.contentWindow); await setBothDocumentDomains(iframe.contentWindow);
...@@ -24,11 +28,15 @@ export async function insertIframe(host, header) { ...@@ -24,11 +28,15 @@ export async function insertIframe(host, header) {
* @param {string} host - The host to calculate the iframe's new src="" * @param {string} host - The host to calculate the iframe's new src=""
* @param {string=} header - The value of the Origin-Isolation header that the * @param {string=} header - The value of the Origin-Isolation header that the
* newly-navigated-to page will set. Omit this to set no header. * newly-navigated-to page will set. Omit this to set no header.
* @param {object=} options - Rarely-used options.
* @param {boolean=} options.redirectFirst - Whether to do a 302 redirect first
* before arriving at the isolated page. The redirecting page will not set
* the Origin-Isolation header.
* @returns {Promise} a promise fulfilled when the load event fires, or rejected * @returns {Promise} a promise fulfilled when the load event fires, or rejected
* if the error event fires * if the error event fires
*/ */
export function navigateIframe(iframeEl, host, header) { export function navigateIframe(iframeEl, host, header, { redirectFirst = false } = {}) {
const url = getSendHeaderURL(host, header); const url = getSendHeaderURL(host, header, { redirectFirst });
const waitPromise = waitForIframe(iframeEl, url); const waitPromise = waitForIframe(iframeEl, url);
iframeEl.src = url; iframeEl.src = url;
...@@ -324,7 +332,7 @@ async function accessOriginIsolated(frameWindow) { ...@@ -324,7 +332,7 @@ async function accessOriginIsolated(frameWindow) {
return waitForMessage(frameWindow); return waitForMessage(frameWindow);
} }
function getSendHeaderURL(host, header, { sendLoadedMessage = false } = {}) { function getSendHeaderURL(host, header, { sendLoadedMessage = false, redirectFirst = false } = {}) {
const url = new URL("send-origin-isolation-header.py", import.meta.url); const url = new URL("send-origin-isolation-header.py", import.meta.url);
url.host = host; url.host = host;
if (header !== undefined) { if (header !== undefined) {
...@@ -333,6 +341,9 @@ function getSendHeaderURL(host, header, { sendLoadedMessage = false } = {}) { ...@@ -333,6 +341,9 @@ function getSendHeaderURL(host, header, { sendLoadedMessage = false } = {}) {
if (sendLoadedMessage) { if (sendLoadedMessage) {
url.searchParams.set("send-loaded-message", ""); url.searchParams.set("send-loaded-message", "");
} }
if (redirectFirst) {
url.searchParams.set("redirect-first", "");
}
return url.href; return url.href;
} }
......
def main(request, response): def main(request, response):
"""Send a response with the Origin-Isolation header given in the "header" """Send a response with the Origin-Isolation header given in the "header"
query parameter, or no header if that is not provided. In either case, the query parameter, or no header if that is not provided. Other query
response will listen for message and messageerror events and echo them back parameters (only their presence/absence matters) are "send-loaded-message"
to the parent. See ./helpers.mjs for how these handlers are used. and "redirect-first", which modify the behavior a bit.
In either case, the response will listen for various messages posted and
coordinate with the sender. See ./helpers.mjs for how these handlers are
used.
""" """
if b"redirect-first" in request.GET:
# Create a new query string, which is the same as the one we're given but
# with the redirect-first component stripped out. This allows tests to use
# any value (or no value) for the other query params, in combination with
# redirect-first.
query_string_pieces = []
if b"header" in request.GET:
query_string_pieces.append(b"header=" + request.GET.first(b"header"))
if b"send-loaded-message" in request.GET:
query_string_pieces.append(b"send-loaded-message")
query_string = "?" + "&".join(query_string_pieces)
return (
302,
[(b"Location", b"/origin-isolation/resources/send-origin-isolation-header.py" + query_string)],
u""
)
if b"header" in request.GET: if b"header" in request.GET:
header = request.GET.first(b"header") header = request.GET.first(b"header")
response.headers.set(b"Origin-Isolation", header) response.headers.set(b"Origin-Isolation", header)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment