Source code
Revision control
Copy as Markdown
Other Tools
var SAME_ORIGIN = true;
var CROSS_ORIGIN = false;
var EXPECT_BLOCK = true;
var EXPECT_LOAD = false;
var SAMEORIGIN_ORIGIN = "{{location[scheme]}}://{{location[host]}}";
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 */);
};
}