summaryrefslogtreecommitdiffstats
path: root/toolkit/identity/tests/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/identity/tests/chrome')
-rw-r--r--toolkit/identity/tests/chrome/.eslintrc.js7
-rw-r--r--toolkit/identity/tests/chrome/chrome.ini13
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content.html32
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content.sjs36
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content_alert.html20
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content_framed.html17
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content_perms.html64
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content_popup.html25
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content_redirect.html2
-rw-r--r--toolkit/identity/tests/chrome/sandbox_content_redirect.html^headers^2
-rw-r--r--toolkit/identity/tests/chrome/test_sandbox.xul324
11 files changed, 542 insertions, 0 deletions
diff --git a/toolkit/identity/tests/chrome/.eslintrc.js b/toolkit/identity/tests/chrome/.eslintrc.js
new file mode 100644
index 000000000..2c669d844
--- /dev/null
+++ b/toolkit/identity/tests/chrome/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+ "extends": [
+ "../../../../testing/mochitest/chrome.eslintrc.js"
+ ]
+};
diff --git a/toolkit/identity/tests/chrome/chrome.ini b/toolkit/identity/tests/chrome/chrome.ini
new file mode 100644
index 000000000..ffaff0fb1
--- /dev/null
+++ b/toolkit/identity/tests/chrome/chrome.ini
@@ -0,0 +1,13 @@
+[DEFAULT]
+skip-if = buildapp == 'b2g' || os == 'android'
+support-files =
+ sandbox_content.html
+ sandbox_content.sjs
+ sandbox_content_alert.html
+ sandbox_content_framed.html
+ sandbox_content_perms.html
+ sandbox_content_popup.html
+ sandbox_content_redirect.html
+ sandbox_content_redirect.html^headers^
+
+[test_sandbox.xul]
diff --git a/toolkit/identity/tests/chrome/sandbox_content.html b/toolkit/identity/tests/chrome/sandbox_content.html
new file mode 100644
index 000000000..9a9b63ac2
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+<meta charset="utf-8">
+<title>Page testing blocked content in the Sandbox</title>
+
+<link rel="stylesheet" src="sandbox_content.sjs?text/css"/>
+
+<script src="sandbox_content.sjs?application/javascript"></script>
+
+</head>
+
+<body>
+
+<img src="sandbox_content.sjs?image/jpeg"/>
+
+<!-- media -->
+<video src="sandbox_content.sjs?video/webm" autoplay="true"></video>
+<audio src="sandbox_content.sjs?audio/ogg" autoplay="true"></audio>
+
+<!-- plugins -->
+<embed src="sandbox_content.sjs?application/x-test"/>
+<object data="sandbox_content.sjs?application/x-test"></object>
+<applet code="sandbox_content.sjs?application/x-java-applet"></applet>
+
+<iframe src="sandbox_content.sjs?text/html"></iframe>
+
+</body>
+
+</html>
diff --git a/toolkit/identity/tests/chrome/sandbox_content.sjs b/toolkit/identity/tests/chrome/sandbox_content.sjs
new file mode 100644
index 000000000..2f562f214
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content.sjs
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function handleRequest(request, response) {
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ let loadedStateKey = "sandbox_content_loaded";
+ switch(request.queryString) {
+ case "reset": {
+ setState(loadedStateKey, "");
+ response.write("reset");
+ break;
+ }
+ case "get_loaded": {
+ response.setHeader("Content-Type", "text/plain", false);
+ let loaded = getState(loadedStateKey);
+ if (loaded)
+ response.write(loaded);
+ else
+ response.write("NOTHING");
+ break;
+ }
+ default: {
+ let contentType = decodeURIComponent(request.queryString);
+ // set the Content-Type equal to the query string
+ response.setHeader("Content-Type", contentType, false);
+ // If any content is loaded, append it's content type in state
+ let loaded = getState(loadedStateKey);
+ if (loaded)
+ loaded += ",";
+ setState(loadedStateKey, loaded + contentType);
+ break;
+ }
+ }
+}
diff --git a/toolkit/identity/tests/chrome/sandbox_content_alert.html b/toolkit/identity/tests/chrome/sandbox_content_alert.html
new file mode 100644
index 000000000..f07308e84
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content_alert.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<!-- Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+<meta charset="utf-8">
+<title>Page creating an alert inside the Sandbox</title>
+
+<script>
+
+alert("The user shouldn't see this");
+
+</script>
+
+</head>
+
+<body>
+
+</body>
+</html>
diff --git a/toolkit/identity/tests/chrome/sandbox_content_framed.html b/toolkit/identity/tests/chrome/sandbox_content_framed.html
new file mode 100644
index 000000000..72b0c49d0
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content_framed.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<!-- Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+<meta charset="utf-8">
+<title>Page testing blocked content in an iframe inside the Sandbox</title>
+
+</head>
+
+<body>
+
+<iframe src="sandbox_content.html"></iframe>
+
+</body>
+
+</html>
diff --git a/toolkit/identity/tests/chrome/sandbox_content_perms.html b/toolkit/identity/tests/chrome/sandbox_content_perms.html
new file mode 100644
index 000000000..d24c683f8
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content_perms.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+ <!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+ <head>
+ <meta charset="utf-8">
+ <title>Page testing content in the Sandbox can't escape</title>
+ <script type="application/javascript;version=1.8">
+ const TEST_BASE = "http://mochi.test:8888/chrome/toolkit/identity/tests/chrome/"
+ const Ci = SpecialPowers.Ci;
+
+ function expectException(aFunc) {
+ try {
+ aFunc();
+ } catch (ex) {
+ return true;
+ }
+ return false;
+ }
+
+ function CcNotPresent() {
+ if (typeof Components === 'undefined')
+ return true;
+ // Components shim doesn't define Components.classes.
+ try {
+ return typeof Components.classes === 'undefined';
+ } catch (e) {
+ return false;
+ }
+ }
+
+ // Build an object with test results (true = pass)
+ let results = {
+ windowTop: window.top == window,
+
+ qiWindow: expectException(function() {
+ let isForced = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .docCharsetIsForced;
+ }),
+
+ ccAccess: !!CcNotPresent(),
+ };
+
+ let resultsJSON = JSON.stringify(results);
+
+ // Send the results to the mochitest server so the test file can retrieve them.
+ let stateURL = TEST_BASE + "sandbox_content.sjs"
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", stateURL + "?" + encodeURIComponent(resultsJSON), true);
+ xhr.onload = function() {
+ if (xhr.status != 200) {
+ dump("Failed sending results\n");
+ }
+ };
+ xhr.send();
+
+ </script>
+ </head>
+
+ <body>
+
+ </body>
+</html>
diff --git a/toolkit/identity/tests/chrome/sandbox_content_popup.html b/toolkit/identity/tests/chrome/sandbox_content_popup.html
new file mode 100644
index 000000000..cb21f706f
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content_popup.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+<meta charset="utf-8">
+<title>Page creating an popup inside the Sandbox</title>
+
+<script>
+
+var strWindowFeatures = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes";
+
+var uri = "data:text/html,";
+uri += encodeURI("<body onload='setTimeout(window.close, 1000)'>");
+
+var win = window.open(uri, "sandbox_popup", strWindowFeatures);
+
+</script>
+
+</head>
+
+<body>
+
+</body>
+</html>
diff --git a/toolkit/identity/tests/chrome/sandbox_content_redirect.html b/toolkit/identity/tests/chrome/sandbox_content_redirect.html
new file mode 100644
index 000000000..7570ffad8
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content_redirect.html
@@ -0,0 +1,2 @@
+<!-- Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ -->
diff --git a/toolkit/identity/tests/chrome/sandbox_content_redirect.html^headers^ b/toolkit/identity/tests/chrome/sandbox_content_redirect.html^headers^
new file mode 100644
index 000000000..7c06340b9
--- /dev/null
+++ b/toolkit/identity/tests/chrome/sandbox_content_redirect.html^headers^
@@ -0,0 +1,2 @@
+HTTP 302 Found
+Location: http://mochi.test:8888/chrome/toolkit/identity/tests/chrome/sandbox_content.html
diff --git a/toolkit/identity/tests/chrome/test_sandbox.xul b/toolkit/identity/tests/chrome/test_sandbox.xul
new file mode 100644
index 000000000..2b353c53b
--- /dev/null
+++ b/toolkit/identity/tests/chrome/test_sandbox.xul
@@ -0,0 +1,324 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
+<!-- Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=762993
+-->
+<window title="Mozilla Bug 762993"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="run_next_test();">
+ <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=762993"
+ target="_blank">Mozilla Bug 762993</a>
+ </body>
+
+ <!-- test code goes here -->
+ <script type="application/javascript;version=1.8">
+ <![CDATA[
+
+ /** Test for Bug 762993 **/
+
+"use strict";
+
+SimpleTest.expectAssertions(1);
+
+SimpleTest.waitForExplicitFinish();
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
+
+const TEST_URL_1 = "https://example.com/";
+// No trailing slash plus port to test normalization
+const TEST_URL_2 = "https://example.com:443";
+
+const TEST_BASE = "http://mochi.test:8888/chrome/toolkit/identity/tests/chrome/"
+const STATE_URL = TEST_BASE + "sandbox_content.sjs"
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+Services.prefs.setBoolPref("toolkit.identity.debug", true);
+
+XPCOMUtils.defineLazyModuleGetter(this, "Sandbox",
+ "resource://gre/modules/identity/Sandbox.jsm");
+
+function check_sandbox(aSandbox, aURL) {
+ ok(aSandbox.id > 0, "valid ID");
+ is(aSandbox._url, aURL, "matching URL (with normalization)");
+ isnot(aSandbox._frame, null, "frame");
+ isnot(aSandbox._container, null, "container");
+ let docPrincipal = aSandbox._frame.contentDocument.nodePrincipal;
+ is(secMan.isSystemPrincipal(docPrincipal), false,
+ "principal must not be system");
+}
+
+/**
+ * Free the sandbox and make sure all properties that are not booleans,
+ * functions or numbers were freed.
+ */
+function free_and_check_sandbox(aSandbox) {
+ SimpleTest.executeSoon(function() {
+ aSandbox.free();
+
+ for(let prop in aSandbox) {
+ // Don't trigger the "id" getter when the frame is supposed to be freed already
+ if (prop == "id")
+ continue;
+ let propType = typeof(aSandbox[prop]);
+ if (propType == "boolean" || propType == "function" || propType == "number")
+ continue;
+ is(aSandbox[prop], null, "freed " + prop);
+ }
+ run_next_test();
+ });
+}
+
+function reset_server_state() {
+ // Now reset the server state
+ let resetReq = new XMLHttpRequest();
+ resetReq.open("GET", STATE_URL + "?reset", false);
+ resetReq.send();
+}
+
+function test_creation() {
+ new Sandbox(TEST_URL_1, function sandboxCB(aSandbox) {
+ check_sandbox(aSandbox, TEST_URL_1);
+ free_and_check_sandbox(aSandbox);
+ });
+}
+
+function test_reload() {
+ new Sandbox(TEST_URL_1, function sandboxCB(aSandbox) {
+ check_sandbox(aSandbox, TEST_URL_1);
+ let originalId = aSandbox.id;
+
+ aSandbox.reload(function sandboxReloadCB(aSandbox) {
+ check_sandbox(aSandbox, TEST_URL_1);
+ is(aSandbox.id, originalId, "Sandbox ID should be the same after reload");
+ free_and_check_sandbox(aSandbox);
+ });
+ });
+}
+
+function test_url_normalization() {
+ new Sandbox(TEST_URL_2, function sandboxCB(aSandbox) {
+ // TEST_URL_2 should be normalized into the form of TEST_URL_1
+ check_sandbox(aSandbox, TEST_URL_1);
+ free_and_check_sandbox(aSandbox);
+ });
+}
+
+/**
+ * Check with the server's state to see what content was loaded then reset it.
+ */
+function check_loaded_content(aSandbox, aNothingShouldLoad, aCallback) {
+
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", STATE_URL + "?get_loaded", true);
+ xhr.onload = function() {
+ let res = xhr.responseText;
+ is(xhr.status, 200, "Check successful response");
+
+ if (aNothingShouldLoad) {
+ is(res, "NOTHING", "Check that nothing was loaded on the server");
+ } else {
+ let allowedTypes = [ "application/javascript", "text/html", "application/x-test" ];
+ let loadedTypes = res == "NOTHING" ? [] : res.split(",");
+
+ for (let loadedType of loadedTypes) {
+ isnot(allowedTypes.indexOf(loadedType), -1, "Check that " + loadedType + " was expected to load"); // TODO
+ }
+
+ isnot(loadedTypes.indexOf("application/javascript"), -1, "Check JS was loaded");
+ isnot(loadedTypes.indexOf("text/html"), -1, "Check iframe was loaded");
+ is(loadedTypes.indexOf("video/webm"), -1, "Check webm was not loaded");
+ is(loadedTypes.indexOf("audio/ogg"), -1, "Check ogg was not loaded");
+
+ // Check that no plugin tags have a type other than TYPE_NULL (failed load)
+ // --
+ // Checking if a channel was opened is not sufficient for plugin tags --
+ // An object tag may still be allowed to load a sub-document, but not a
+ // plugin, so it will open a channel but then abort when it gets a
+ // plugin-type.
+ let doc = aSandbox._frame.contentDocument;
+ let nullType = Components.interfaces.nsIObjectLoadingContent.TYPE_NULL;
+ for (let tag of doc.querySelectorAll("embed, object, applet")) {
+ tag instanceof Components.interfaces.nsIObjectLoadingContent;
+ is(tag.displayedType, nullType, "Check that plugin did not load content");
+ }
+ }
+
+ reset_server_state();
+
+ aCallback();
+ };
+ xhr.send();
+}
+
+/**
+ * Helper to check that only certain content is loaded on creation and during reload.
+ */
+function check_disabled_content(aSandboxURL, aNothingShouldLoad = false) {
+ new Sandbox(aSandboxURL, function sandboxCB(aSandbox) {
+ check_sandbox(aSandbox, aSandboxURL);
+ let originalId = aSandbox.id;
+
+ setTimeout(function() {
+ check_loaded_content(aSandbox, aNothingShouldLoad, function checkFinished() {
+
+ info("reload the sandbox content");
+ aSandbox.reload(function sandboxReloadCB(aSandbox) {
+ check_sandbox(aSandbox, aSandboxURL);
+ is(aSandbox.id, originalId, "Sandbox ID should be the same after reload");
+
+ setTimeout(function() {
+ check_loaded_content(aSandbox, aNothingShouldLoad, function reloadCheckFinished() {
+ free_and_check_sandbox(aSandbox);
+ });
+ }, 5000);
+ });
+ });
+ }, 5000);
+ });
+}
+
+function test_disabled_content() {
+ let url = TEST_BASE + "sandbox_content.html";
+ check_disabled_content(url);
+}
+
+// Same as test above but with content in an iframe.
+function test_disabled_content_framed() {
+ let url = TEST_BASE + "sandbox_content_framed.html";
+ check_disabled_content(url);
+}
+
+function test_redirect() {
+ let url = TEST_BASE + "sandbox_content_redirect.html";
+ check_disabled_content(url);
+}
+
+function WindowObserver(aCallback) {
+ this.observe = function(aSubject, aTopic, aData) {
+ if (aTopic != "domwindowopened") {
+ return;
+ }
+ Services.ww.unregisterNotification(this);
+
+ let domWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ ok(!domWin, "No window should be opened");
+ SimpleTest.executeSoon(function() {
+ info("Closing opened window");
+ domWin.close();
+ aCallback();
+ });
+ }
+}
+
+// Can the sandbox call window.alert() or popup other UI?
+function test_alert() {
+ let alertURL = TEST_BASE + "sandbox_content_alert.html";
+
+ new Sandbox(alertURL, function sandboxCB(aSandbox) {
+ check_sandbox(aSandbox, alertURL);
+ setTimeout(function() {
+
+ let win = Services.wm.getMostRecentWindow(null);
+ isnot(win.document.documentElement.getAttribute("id"), "commonDialog",
+ "Make sure most recent window is not a dialog");
+ if (win.document.documentElement.getAttribute("id") == "commonDialog") {
+ // If a dialog did open, close it so we don't interfere with future tests
+ win.close()
+ }
+
+ free_and_check_sandbox(aSandbox);
+ }, 1000);
+ });
+}
+
+// Can the sandboxed page open a popup with window.open?
+function test_popup() {
+ let alertURL = TEST_BASE + "sandbox_content_popup.html";
+ let theSandbox;
+ function continueTest() {
+ // avoid double-free
+ if (!theSandbox)
+ return;
+ free_and_check_sandbox(theSandbox);
+ theSandbox = null;
+ }
+ let winObs = new WindowObserver(continueTest);
+ Services.ww.registerNotification(winObs);
+ new Sandbox(alertURL, function sandboxCB(aSandbox) {
+ theSandbox = aSandbox;
+ check_sandbox(aSandbox, alertURL);
+ // Wait 5 seconds to see if the window is going to open.
+ setTimeout(function() {
+ Services.ww.unregisterNotification(winObs);
+ continueTest();
+ }, 5000);
+ });
+}
+
+// Loading a page with a bad cert
+function test_bad_cert() {
+ let url = TEST_BASE + "sandbox_content.sjs?text/html";
+ url = url.replace("http://mochi.test:8888", "https://untrusted.example.com");
+ check_disabled_content(url, /*nothingShouldLoad=*/true);
+}
+
+// Loading a page to check window.top and other permissions.
+function test_frame_perms() {
+ let url = TEST_BASE + "sandbox_content_perms.html";
+ new Sandbox(url, function sandboxCB(aSandbox) {
+ check_sandbox(aSandbox, url);
+
+ // Give the content time to load
+ setTimeout(function() {
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", STATE_URL + "?get_loaded", true);
+ xhr.responseType = "json";
+ xhr.onload = function() {
+ is(xhr.status, 200, "Check successful response");
+ is(typeof(xhr.response), "object", "Check response is object");
+ is(Object.keys(xhr.response).length, 3, "Check the number of perm. tests");
+ for (let test in xhr.response) {
+ ok(xhr.response[test], "Check result of " + test);
+ }
+
+ reset_server_state();
+ free_and_check_sandbox(aSandbox);
+ };
+ xhr.send();
+ }, 3000);
+ });
+}
+
+let TESTS = [test_creation, test_reload, test_url_normalization];
+TESTS.push(test_disabled_content, test_disabled_content_framed);
+TESTS.push(test_alert, test_popup, test_bad_cert);
+TESTS.push(test_redirect, test_frame_perms);
+
+function run_next_test() {
+ if (TESTS.length) {
+ let test = TESTS.shift();
+ info(test.name);
+ test();
+ } else {
+ Services.prefs.clearUserPref("toolkit.identity.debug");
+ SimpleTest.finish();
+ }
+}
+
+ ]]>
+ </script>
+</window>