Bug 624883 - Tests for ensuring that view-source is forbidden in iframes. r=bz

This commit is contained in:
Bob Owen 2014-01-23 16:02:10 +00:00
parent 2c77d04fcf
commit abddb2e8d5
9 changed files with 209 additions and 45 deletions

View File

@ -15,9 +15,6 @@
<tt> aa_block: /* innermost frame denies a */</tt><br/>
<iframe id='aa_block'></iframe><br/>
<tt> aa2_block: /* innermost frame (view-source: URL) denies a */</tt><br/>
<iframe id='aa2_block'></iframe><br/>
<tt> ab_allow: /* innermost frame allows a */</tt><br/>
<iframe id='ab_allow'></iframe><br/>

View File

@ -22,10 +22,6 @@ function setupFrames() {
elt.src = base.a + "?testid=aa_block&internalframe=aa_b&csp=" +
escape("allow 'none'; frame-ancestors 'none'; script-src 'self'");
elt = $('aa2_block');
elt.src = "view-source:" + base.a + "?testid=aa2_block&internalframe=aa_b&csp=" +
escape("allow 'none'; frame-ancestors 'none'; script-src 'self'");
elt = $('ab_allow');
elt.src = base.b + "?testid=ab_allow&internalframe=ab_a&csp=" +
escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");

View File

@ -15,9 +15,6 @@
<tt> aa_block: /* innermost frame denies a */</tt><br/>
<iframe id='aa_block_spec_compliant'></iframe><br/>
<tt> aa2_block: /* innermost frame (view-source: URL) denies a */</tt><br/>
<iframe id='aa2_block_spec_compliant'></iframe><br/>
<tt> ab_allow: /* innermost frame allows a */</tt><br/>
<iframe id='ab_allow_spec_compliant'></iframe><br/>

View File

@ -22,10 +22,6 @@ function setupFrames() {
elt.src = base.a + "?testid=aa_block_spec_compliant&internalframe=aa_b&csp=" +
escape("default-src 'none'; frame-ancestors 'none'; script-src 'self'");
elt = $('aa2_block_spec_compliant');
elt.src = "view-source:" + base.a + "?testid=aa2_block_spec_compliant&internalframe=aa_b&csp=" +
escape("default-src 'none'; frame-ancestors 'none'; script-src 'self'");
elt = $('ab_allow_spec_compliant');
elt.src = base.b + "?testid=ab_allow_spec_compliant&internalframe=ab_a&csp=" +
escape("default-src 'none'; frame-ancestors " + host.a + "; script-src 'self'");

View File

@ -20,7 +20,6 @@ var path = "/tests/content/base/test/csp/";
var framesThatShouldLoad = {
aa_allow: -1, /* innermost frame allows a */
//aa_block: -1, /* innermost frame denies a */
//aa2_block: -1, /* innermost frame denies a */
ab_allow: -1, /* innermost frame allows a */
//ab_block: -1, /* innermost frame denies a */
aba_allow: -1, /* innermost frame allows b,a */
@ -31,7 +30,6 @@ var framesThatShouldLoad = {
//abb2_block: -1, /* innermost frame denies a */
aa_allow_spec_compliant: -1, /* innermost frame allows a *
//aa_block_spec_compliant: -1, /* innermost frame denies a */
//aa2_block_spec_compliant: -1, /* innermost frame denies a */
ab_allow_spec_compliant: -1, /* innermost frame allows a */
//ab_block_spec_compliant: -1, /* innermost frame denies a */
aba_allow_spec_compliant: -1, /* innermost frame allows b,a */
@ -42,7 +40,7 @@ var framesThatShouldLoad = {
//abb2_block_spec_compliant: -1, /* innermost frame denies a */
};
var expectedViolationsLeft = 14;
var expectedViolationsLeft = 12;
// This is used to watch the blocked data bounce off CSP and allowed data
// get sent out to the wire.

View File

@ -42,6 +42,7 @@ support-files =
bug909218.js
bug92598_window.xul
docshell_helpers.js
file_viewsource_forbidden_in_iframe.html
generic.html
mozFrameType_window.xul
@ -78,3 +79,4 @@ support-files =
[test_mozFrameType.xul]
[test_principalInherit.xul]
[test_private_hidden_window.html]
[test_viewsource_forbidden_in_iframe.xul]

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test ifranes for view-source forbidden in iframe tests</title>
</head>
<body>
<iframe id="testIframe"></iframe>
<iframe id="refIframe"></iframe>
</body>
</html>

View File

@ -0,0 +1,180 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin/"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=624883
-->
<window title="Mozilla Bug 624883"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=624883"
target="_blank">Mozilla Bug 624883</a>
</body>
<!-- test code goes here -->
<iframe type="content" onload="startTest()" src="file_viewsource_forbidden_in_iframe.html"></iframe>
<script type="application/javascript">
<![CDATA[
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
SimpleTest.waitForExplicitFinish();
// We create a promise that will resolve with the error message
// on a network error page load and reject on any other load.
function createNetworkErrorMessagePromise(frame) {
return new Promise(function(resolve, reject) {
// Error pages do not fire "load" events, so use a progressListener.
var originalDocumentURI = frame.contentDocument.documentURI;
var progressListener = {
onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
// Make sure nothing other than an error page is loaded.
if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) {
reject("location change was not to an error page");
}
},
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
// Wait until the documentURI changes (from about:blank) this should
// be the error page URI.
var documentURI = frame.contentDocument.documentURI;
if (documentURI == originalDocumentURI) {
return;
}
aWebProgress.removeProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_ALL);
var matchArray = /about:neterror\?.*&d=([^&]*)/.exec(documentURI);
if (!matchArray) {
reject("no network error message found in URI")
return;
}
var errorMsg = matchArray[1];
resolve(decodeURIComponent(errorMsg));
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])
};
frame.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress)
.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION |
Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);
});
}
function startTest() {
// Get a reference message that we know will be an unknown protocol message,
// so we can use it for comparisons in the test cases.
var refIframe = window[0].document.getElementById("refIframe");
var refErrorPromise = createNetworkErrorMessagePromise(refIframe);
refErrorPromise.then(
function(msg) {
window.refErrorMsg = msg;
var testIframe = window[0].document.getElementById("testIframe");
// Run test cases on load of "about:blank", so that the URI always changes
// and we can detect this in our Promise.
testIframe.onload = runNextTestCase;
testIframe.src = "about:blank";
},
function(reason) {
ok(false, "Could not get reference error message", reason);
SimpleTest.finish();
})
.catch(function(e) {
ok(false, "Unexpected exception thrown getting reference error message", exception);
});
refIframe.src = "wibble://example.com";
}
function runTestCase(testCase) {
var testIframe = window[0].document.getElementById("testIframe");
var expectedErrorMsg = window.refErrorMsg.replace("wibble", testCase.expectedProtocolList);
var testErrorPromise = createNetworkErrorMessagePromise(testIframe);
testErrorPromise.then(
function(actualErrorMsg) {
is(actualErrorMsg, expectedErrorMsg, testCase.desc);
testIframe.src = "about:blank";
},
function(reason) {
ok(false, testCase.desc, reason);
testIframe.src = "about:blank";
})
.catch(function(e) {
ok(false, testCase.desc + " - unexpected exception thrown", exception);
});
testIframe.src = testCase.protocols + "://example.com/!/";
}
var testCaseIndex = -1;
testCases = [
{
desc: "Test 1: view-source should not be allowed in an iframe",
protocols: "view-source:http",
expectedProtocolList: "view-source, http"
},
{
desc: "Test 2: feed:view-source should not be allowed in an iframe",
protocols: "feed:view-source:http",
expectedProtocolList: "feed, view-source, http"
},
{
desc: "Test 3: jar:view-source should not be allowed in an iframe",
protocols: "jar:view-source:http",
expectedProtocolList: "jar, view-source, http"
},
{
desc: "Test 4: pcast:view-source should not be allowed in an iframe",
protocols: "pcast:view-source:http",
expectedProtocolList: "pcast, view-source, http"
},
{
desc: "Test 5: pcast:feed:view-source should not be allowed in an iframe",
protocols: "pcast:feed:view-source:http",
expectedProtocolList: "pcast, feed, view-source, http"
},
{
desc: "Test 6: if invalid protocol first should report before view-source",
protocols: "wibble:view-source:http",
// Nothing after the invalid protocol gets set as a proper nested URI,
// so the list stops there.
expectedProtocolList: "wibble"
},
{
desc: "Test 7: if view-source first should report before invalid protocol",
protocols: "view-source:wibble:http",
expectedProtocolList: "view-source, wibble"
}
];
function runNextTestCase() {
++testCaseIndex;
if (testCaseIndex == testCases.length) {
SimpleTest.finish();
return;
}
runTestCase(testCases[testCaseIndex]);
}
]]>
</script>
</window>

View File

@ -2,7 +2,6 @@
<html>
<head>
<title>Test for view source</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
@ -25,38 +24,26 @@
return xhr.responseText;
}
// Start a "view source" test using the document at "testUrl". Note that
// the test will actually complete asynchronously.
function startViewSourceTest(testUrl) {
// We will "view" the source of the document in an IFRAME.
// If everything is working correctly, the "source" will simply be the
// text content of the IFRAME document's top element.
// We will "view" the source of the document in a new window.
// If everything is working correctly, the "source" will simply be the
// text content of the new window's document's body element.
// We have to use a window as view-source: is only allowed in top level,
// see bug 624883.
// Create the IFRAME.
var iframe = document.createElement('iframe');
iframe.src = "view-source:" + testUrl;
// Open the new window.
var windowWithSource = window.open("about:blank");
// The actual test will be carried out inside the IFRAME's onload handler.
iframe.onload = function () {
// The actual test will be carried out inside the window's onload handler.
windowWithSource.onload = function () {
var apparentSource = this.document.body.textContent;
var actualSource = fetch(location.href);
is(apparentSource, actualSource, "Sources should match");
var apparentSource = this.contentDocument.body.textContent;
var actualSource = fetch(testUrl);
// OK, verify that the apparent source and the actual source agree.
ok(apparentSource == actualSource, "Sources should match");
SimpleTest.finish();
}
// Our test IFRAME is ready to go. However, it will not load until we
// actually append it to the document. Do that now. Note that the test
// itself will run asynchronously some time after this function returns.
document.body.appendChild(iframe);
windowWithSource.close()
SimpleTest.finish();
}
// Start a test using this document as the test document.
startViewSourceTest(document.location.href);
windowWithSource.location.href = "view-source:" + location.href;
</script>
</body>