284 lines
11 KiB
HTML
284 lines
11 KiB
HTML
<!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="/common/get-host-info.sub.js"></script>
|
|
<script src="/common/utils.js"></script>
|
|
<script src="/common/dispatcher/dispatcher.js"></script>
|
|
<!-- Pull in executor_path needed by newPopup / newIframe -->
|
|
<script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"></script>
|
|
<!-- Pull in importScript / newPopup / newIframe -->
|
|
<script src="/html/anonymous-iframe/resources/common.js"></script>
|
|
<body>
|
|
<script>
|
|
|
|
const navigation_handle_null = "Navigation handle returns null";
|
|
const navigation_handle_not_null = "Navigation handle returns not null";
|
|
const opener_null_response = "Window.opener is null";
|
|
const opener_not_null_response = "Window.opener isn't null";
|
|
|
|
const does_blob_url_open_return_handle = (blob_url, response_queue_name) => `
|
|
async function test() {
|
|
const handle = window.open("${blob_url}")
|
|
if (!handle) {
|
|
return send("${response_queue_name}", "${navigation_handle_null}");
|
|
}
|
|
|
|
return send("${response_queue_name}", "${navigation_handle_not_null}");
|
|
}
|
|
await test();
|
|
`;
|
|
|
|
const add_iframe_js = (iframe_origin, response_queue_uuid) => `
|
|
const importScript = ${importScript};
|
|
await importScript("/html/cross-origin-embedder-policy/credentialless" +
|
|
"/resources/common.js");
|
|
await importScript("/html/anonymous-iframe/resources/common.js");
|
|
await importScript("/common/utils.js");
|
|
|
|
// dispatcher.js has already been loaded by the popup this is running in.
|
|
await send("${response_queue_uuid}", newIframe("${iframe_origin}"));
|
|
`;
|
|
|
|
const same_site_origin = get_host_info().HTTPS_ORIGIN;
|
|
const cross_site_origin = get_host_info().HTTPS_NOTSAMESITE_ORIGIN;
|
|
|
|
async function create_test_iframes(t, response_queue_uuid) {
|
|
assert_equals("https://" + window.location.host, same_site_origin,
|
|
"this test assumes that the page's window.location.host corresponds to " +
|
|
"get_host_info().HTTPS_ORIGIN");
|
|
|
|
// Create a same-origin iframe in a cross-site popup.
|
|
const not_same_site_popup_uuid = newPopup(t, cross_site_origin);
|
|
await send(not_same_site_popup_uuid,
|
|
add_iframe_js(same_site_origin, response_queue_uuid));
|
|
const cross_site_iframe_uuid = await receive(response_queue_uuid);
|
|
|
|
// Create a same-origin iframe in a same-site popup.
|
|
const same_origin_popup_uuid = newPopup(t, same_site_origin);
|
|
await send(same_origin_popup_uuid,
|
|
add_iframe_js(same_site_origin, response_queue_uuid));
|
|
const same_site_iframe_uuid = await receive(response_queue_uuid);
|
|
|
|
return [cross_site_iframe_uuid, same_site_iframe_uuid];
|
|
}
|
|
|
|
const opener_check_frame_html = (noopener_response_queue) => `
|
|
<!doctype html>
|
|
<!-- dispatcher.js requires the baseURI to be set in order to compute
|
|
the server path correctly in the blob URL page. -->
|
|
<base href="${window.location.href}">
|
|
<script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"><\/script>
|
|
<script src="/html/anonymous-iframe/resources/common.js"><\/script>
|
|
<script src="/common/utils.js"><\/script>
|
|
<script src="/common/dispatcher/dispatcher.js"><\/script>
|
|
<script>
|
|
if (window.opener === null) {
|
|
send("${noopener_response_queue}", "${opener_null_response}")
|
|
} else {
|
|
send("${noopener_response_queue}", "${opener_not_null_response}")
|
|
}
|
|
<\/script>
|
|
`;
|
|
|
|
// Tests blob URL window.open for same and cross partition iframes.
|
|
promise_test(t => {
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
// Creates same and cross partition iframes.
|
|
const response_queue_uuid = token();
|
|
const noopener_response_queue = token();
|
|
|
|
const [cross_site_iframe_uuid, same_site_iframe_uuid] =
|
|
await create_test_iframes(t, response_queue_uuid);
|
|
|
|
const blob = new Blob([opener_check_frame_html(noopener_response_queue)], {type : "text/html"});
|
|
const blob_url = URL.createObjectURL(blob);
|
|
|
|
// Attempt to open blob URL in cross partition iframe.
|
|
await send(cross_site_iframe_uuid, does_blob_url_open_return_handle(blob_url, response_queue_uuid));
|
|
const response_1 = await receive(response_queue_uuid);
|
|
if (response_1 !== navigation_handle_null) {
|
|
reject(`Blob URL handle wasn't null in not-same-top-level-site iframe: ${response_1}`);
|
|
}
|
|
const noopener_response_1 = await receive(noopener_response_queue);
|
|
if (noopener_response_1 !== opener_null_response) {
|
|
reject(`Blob URL page opener wasn't null in not-same-top-level-site iframe.`);
|
|
}
|
|
|
|
// Attempt to open blob URL in same partition iframe.
|
|
await send(same_site_iframe_uuid, does_blob_url_open_return_handle(blob_url, response_queue_uuid));
|
|
const response_2 = await receive(response_queue_uuid);
|
|
if (response_2 !== navigation_handle_not_null) {
|
|
reject(`Blob URL wasn't opened in same-top-level-site iframe: ${response_2}`);
|
|
}
|
|
const noopener_response_2 = await receive(noopener_response_queue);
|
|
if (noopener_response_2 !== opener_not_null_response) {
|
|
reject(`Blob URL page opener was null in same-top-level-site iframe`);
|
|
}
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
}, "Blob URL window.open should enforce noopener for a cross-top-level-site navigation");
|
|
|
|
const blob_url_iframe_html = (response_queue_uuid, message) => `
|
|
<!doctype html>
|
|
<!-- dispatcher.js requires the baseURI to be set in order to compute
|
|
the server path correctly in the blob URL page. -->
|
|
<base href="${window.location.href}">
|
|
<script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"><\/script>
|
|
<script src="/html/anonymous-iframe/resources/common.js"><\/script>
|
|
<script src="/common/utils.js"><\/script>
|
|
<script src="/common/dispatcher/dispatcher.js"><\/script>
|
|
<script>
|
|
send("${response_queue_uuid}", "${message}");
|
|
<\/script>
|
|
`;
|
|
|
|
const create_iframe_with_blob_url = (blob_url, response_queue_uuid) => `
|
|
const iframe = document.createElement('iframe');
|
|
iframe.src = "${blob_url}";
|
|
iframe.onload = () => {
|
|
const same_site_message = "same_partition_loaded";
|
|
const blob_url_iframe_html = ${blob_url_iframe_html};
|
|
const same_top_level_site_blob = new Blob([blob_url_iframe_html("${response_queue_uuid}", same_site_message)], {type : "text/html"});
|
|
const same_top_level_site_blob_url = URL.createObjectURL(same_top_level_site_blob);
|
|
const iframe2 = document.createElement('iframe');
|
|
iframe2.src = same_top_level_site_blob_url;
|
|
document.body.appendChild(iframe2);
|
|
};
|
|
document.body.appendChild(iframe);
|
|
`;
|
|
|
|
// Tests blob URL subframe navigations for same and cross partition iframes.
|
|
promise_test(t => {
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
// Creates same and cross partition iframes.
|
|
const response_queue_uuid = token();
|
|
const cross_site_message = "cross_partition_loaded";
|
|
|
|
const [cross_site_iframe_uuid, same_site_iframe_uuid] =
|
|
await create_test_iframes(t, response_queue_uuid);
|
|
|
|
// Create blob URL for the cross-site test.
|
|
const cross_site_blob = new Blob([blob_url_iframe_html(response_queue_uuid, cross_site_message)], {type: "text/html"});
|
|
const cross_site_blob_url = URL.createObjectURL(cross_site_blob);
|
|
|
|
// Attempt to open blob URL in cross partition iframe.
|
|
await send(cross_site_iframe_uuid, create_iframe_with_blob_url(cross_site_blob_url, response_queue_uuid));
|
|
|
|
const response = await receive(response_queue_uuid);
|
|
if (response === cross_site_message) {
|
|
reject(`Blob URL subframe navigation succeeded in not-same-top-level-site iframe.`);
|
|
}
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
}, "Blob URL should partition subframe navigation.");
|
|
|
|
const open_blob_url_window_via_a_click = (blob_url) => `
|
|
const link = document.createElement("a");
|
|
link.href = "${blob_url}";
|
|
link.target = "_blank";
|
|
link.rel = "opener";
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
`;
|
|
|
|
// Tests blob URL `<a target="_blank" rel="opener">` click for same and cross partition iframes.
|
|
promise_test(t => {
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
// Creates same and cross partition iframes.
|
|
const noopener_response_queue = token();
|
|
|
|
const [cross_site_iframe_uuid, same_site_iframe_uuid] = await create_test_iframes(t, token());
|
|
|
|
const blob = new Blob([opener_check_frame_html(noopener_response_queue)], {type : "text/html"});
|
|
const blob_url = URL.createObjectURL(blob);
|
|
|
|
// Attempt to click blob URL in cross partition iframe.
|
|
await send(cross_site_iframe_uuid, open_blob_url_window_via_a_click(blob_url));
|
|
const noopener_response_1 = await receive(noopener_response_queue);
|
|
if (noopener_response_1 !== opener_null_response) {
|
|
reject(`Blob URL page opener wasn't null in not-same-top-level-site iframe.`);
|
|
}
|
|
|
|
// Attempt to click blob URL in same partition iframe.
|
|
await send(same_site_iframe_uuid, open_blob_url_window_via_a_click(blob_url));
|
|
const noopener_response_2 = await receive(noopener_response_queue);
|
|
if (noopener_response_2 !== opener_not_null_response) {
|
|
reject(`Blob URL page opener was null in same-top-level-site iframe`);
|
|
}
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
}, "Blob URL link click should enforce noopener for a cross-top-level-site navigation");
|
|
|
|
const open_blob_url_window_via_area_click = (blob_url) => `
|
|
const canvas = document.createElement("canvas");
|
|
canvas.height = 1;
|
|
canvas.width = 1;
|
|
const dataURL = canvas.toDataURL();
|
|
|
|
const image = document.createElement("img");
|
|
image.src = dataURL;
|
|
document.body.appendChild(image);
|
|
|
|
const map = document.createElement("map");
|
|
map.name = "map";
|
|
image.useMap = "#map";
|
|
document.body.appendChild(map);
|
|
|
|
const area = document.createElement("area");
|
|
area.shape = "rect";
|
|
area.coords = "0,0,1,1";
|
|
area.href = "${blob_url}";
|
|
area.target = "_blank";
|
|
area.rel = "opener";
|
|
map.appendChild(area);
|
|
area.click();
|
|
`;
|
|
|
|
// Tests blob URL `<area target="_blank" rel="opener">` click for same and cross partition iframes.
|
|
promise_test(t => {
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
// Creates same and cross partition iframes.
|
|
const noopener_response_queue = token();
|
|
|
|
const [cross_site_iframe_uuid, same_site_iframe_uuid] = await create_test_iframes(t, token());
|
|
|
|
const blob = new Blob([opener_check_frame_html(noopener_response_queue)], {type : "text/html"});
|
|
const blob_url = URL.createObjectURL(blob);
|
|
|
|
// Attempt to click blob URL in cross partition iframe.
|
|
await send(cross_site_iframe_uuid, open_blob_url_window_via_area_click(blob_url));
|
|
const noopener_response_1 = await receive(noopener_response_queue);
|
|
if (noopener_response_1 !== opener_null_response) {
|
|
reject(`Blob URL page opener wasn't null in not-same-top-level-site iframe.`);
|
|
}
|
|
|
|
// Attempt to click blob URL in same partition iframe.
|
|
await send(same_site_iframe_uuid, open_blob_url_window_via_area_click(blob_url));
|
|
const noopener_response_2 = await receive(noopener_response_queue);
|
|
if (noopener_response_2 !== opener_not_null_response) {
|
|
reject(`Blob URL page opener was null in same-top-level-site iframe`);
|
|
}
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
}, "Blob URL area element click should enforce noopener for a cross-top-level-site navigation");
|
|
|
|
</script>
|
|
</body>
|