summaryrefslogtreecommitdiffstats
path: root/dom/security/test
diff options
context:
space:
mode:
Diffstat (limited to 'dom/security/test')
-rw-r--r--dom/security/test/csp/file_child-src_worker-redirect.html7
-rw-r--r--dom/security/test/csp/file_frame_ancestors_ro.html1
-rw-r--r--dom/security/test/csp/file_frame_ancestors_ro.html^headers^1
-rw-r--r--dom/security/test/csp/file_frame_src.js14
-rw-r--r--dom/security/test/csp/file_frame_src_child_governs.html10
-rw-r--r--dom/security/test/csp/file_frame_src_frame_governs.html10
-rw-r--r--dom/security/test/csp/file_frame_src_inner.html5
-rw-r--r--dom/security/test/csp/file_ignore_xfo.html10
-rw-r--r--dom/security/test/csp/file_ignore_xfo.html^headers^3
-rw-r--r--dom/security/test/csp/file_image_nonce.html39
-rw-r--r--dom/security/test/csp/file_image_nonce.html^headers^2
-rw-r--r--dom/security/test/csp/file_punycode_host_src.js2
-rw-r--r--dom/security/test/csp/file_punycode_host_src.sjs45
-rw-r--r--dom/security/test/csp/file_ro_ignore_xfo.html10
-rw-r--r--dom/security/test/csp/file_ro_ignore_xfo.html^headers^3
-rw-r--r--dom/security/test/csp/file_spawn_service_worker.js1
-rw-r--r--dom/security/test/csp/file_spawn_shared_worker.js7
-rw-r--r--dom/security/test/csp/file_spawn_worker.js1
-rw-r--r--dom/security/test/csp/file_upgrade_insecure_navigation.sjs79
-rw-r--r--dom/security/test/csp/file_websocket_explicit.html31
-rw-r--r--dom/security/test/csp/file_websocket_self.html31
-rw-r--r--dom/security/test/csp/file_websocket_self_wsh.py7
-rw-r--r--dom/security/test/csp/file_worker_src.js52
-rw-r--r--dom/security/test/csp/file_worker_src_child_governs.html9
-rw-r--r--dom/security/test/csp/file_worker_src_script_governs.html9
-rw-r--r--dom/security/test/csp/file_worker_src_worker_governs.html9
-rw-r--r--dom/security/test/csp/mochitest.ini36
-rw-r--r--dom/security/test/csp/test_child-src_worker.html6
-rw-r--r--dom/security/test/csp/test_frame_ancestors_ro.html69
-rw-r--r--dom/security/test/csp/test_frame_src.html84
-rw-r--r--dom/security/test/csp/test_ignore_xfo.html59
-rw-r--r--dom/security/test/csp/test_image_nonce.html60
-rw-r--r--dom/security/test/csp/test_punycode_host_src.html81
-rw-r--r--dom/security/test/csp/test_upgrade_insecure_navigation.html103
-rw-r--r--dom/security/test/csp/test_websocket_self.html61
-rw-r--r--dom/security/test/csp/test_worker_src.html94
-rw-r--r--dom/security/test/general/browser.ini14
-rw-r--r--dom/security/test/general/browser_test_data_download.js37
-rw-r--r--dom/security/test/general/browser_test_data_text_csv.js37
-rw-r--r--dom/security/test/general/browser_test_toplevel_data_navigations.js54
-rw-r--r--dom/security/test/general/browser_test_view_image_data_navigation.js30
-rw-r--r--dom/security/test/general/file_block_toplevel_data_navigation.html14
-rw-r--r--dom/security/test/general/file_block_toplevel_data_navigation2.html29
-rw-r--r--dom/security/test/general/file_block_toplevel_data_navigation3.html13
-rw-r--r--dom/security/test/general/file_block_toplevel_data_redirect.sjs14
-rw-r--r--dom/security/test/general/file_data_download.html14
-rw-r--r--dom/security/test/general/file_data_text_csv.html14
-rw-r--r--dom/security/test/general/file_toplevel_data_meta_redirect.html10
-rw-r--r--dom/security/test/general/file_toplevel_data_navigations.sjs14
-rw-r--r--dom/security/test/general/file_view_image_data_navigation.html12
-rw-r--r--dom/security/test/general/mochitest.ini12
-rw-r--r--dom/security/test/general/test_allow_opening_data_json.html39
-rw-r--r--dom/security/test/general/test_allow_opening_data_pdf.html41
-rw-r--r--dom/security/test/general/test_block_script_wrong_mime.html6
-rw-r--r--dom/security/test/general/test_block_toplevel_data_img_navigation.html53
-rw-r--r--dom/security/test/general/test_block_toplevel_data_navigation.html86
-rw-r--r--dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html1
-rw-r--r--dom/security/test/gtest/TestCSPParser.cpp6
-rw-r--r--dom/security/test/moz.build1
59 files changed, 1588 insertions, 14 deletions
diff --git a/dom/security/test/csp/file_child-src_worker-redirect.html b/dom/security/test/csp/file_child-src_worker-redirect.html
index 188f173b8..b0029935c 100644
--- a/dom/security/test/csp/file_child-src_worker-redirect.html
+++ b/dom/security/test/csp/file_child-src_worker-redirect.html
@@ -23,11 +23,8 @@
);
worker.onerror = function(error) {
- var msg = error.message;
- if (msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/)) {
- // this means CSP blocked it
- msg = "blocked";
- }
+ // this means CSP blocked it
+ var msg = !("message" in error) ? "blocked" : e.message;
window.parent.postMessage({id:page_id, message:msg}, 'http://mochi.test:8888');
error.preventDefault();
};
diff --git a/dom/security/test/csp/file_frame_ancestors_ro.html b/dom/security/test/csp/file_frame_ancestors_ro.html
new file mode 100644
index 000000000..ff5ae9cf9
--- /dev/null
+++ b/dom/security/test/csp/file_frame_ancestors_ro.html
@@ -0,0 +1 @@
+<html><body>Child Document</body></html>
diff --git a/dom/security/test/csp/file_frame_ancestors_ro.html^headers^ b/dom/security/test/csp/file_frame_ancestors_ro.html^headers^
new file mode 100644
index 000000000..d018af3a9
--- /dev/null
+++ b/dom/security/test/csp/file_frame_ancestors_ro.html^headers^
@@ -0,0 +1 @@
+Content-Security-Policy-Report-Only: frame-ancestors 'none'; report-uri http://mochi.test:8888/foo.sjs
diff --git a/dom/security/test/csp/file_frame_src.js b/dom/security/test/csp/file_frame_src.js
new file mode 100644
index 000000000..8e81f0743
--- /dev/null
+++ b/dom/security/test/csp/file_frame_src.js
@@ -0,0 +1,14 @@
+let testframe = document.getElementById("testframe");
+testframe.onload = function() {
+ parent.postMessage({
+ result: "frame-allowed",
+ href: document.location.href,
+ }, "*");
+}
+testframe.onerror = function() {
+ parent.postMessage({
+ result: "frame-blocked",
+ href: document.location.href,
+ }, "*");
+}
+testframe.src = "file_frame_src_inner.html"
diff --git a/dom/security/test/csp/file_frame_src_child_governs.html b/dom/security/test/csp/file_frame_src_child_governs.html
new file mode 100644
index 000000000..a51cb75be
--- /dev/null
+++ b/dom/security/test/csp/file_frame_src_child_governs.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="child-src https://example.com">";
+</head>
+<body>
+<iframe id="testframe"></iframe>
+<script type="text/javascript" src="file_frame_src.js"></script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_frame_src_frame_governs.html b/dom/security/test/csp/file_frame_src_frame_governs.html
new file mode 100644
index 000000000..2c5d5857f
--- /dev/null
+++ b/dom/security/test/csp/file_frame_src_frame_governs.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="frame-src https://example.com; child-src 'none'">";
+</head>
+<body>
+<iframe id="testframe"></iframe>
+<script type="text/javascript" src="file_frame_src.js"></script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_frame_src_inner.html b/dom/security/test/csp/file_frame_src_inner.html
new file mode 100644
index 000000000..4a2fc6095
--- /dev/null
+++ b/dom/security/test/csp/file_frame_src_inner.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+dummy iframe
+</body>
+</html>
diff --git a/dom/security/test/csp/file_ignore_xfo.html b/dom/security/test/csp/file_ignore_xfo.html
new file mode 100644
index 000000000..6746a3adb
--- /dev/null
+++ b/dom/security/test/csp/file_ignore_xfo.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title>
+</head>
+<body>
+<div id="cspmessage">Ignoring XFO because of CSP</div>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ignore_xfo.html^headers^
new file mode 100644
index 000000000..e93f9e3ec
--- /dev/null
+++ b/dom/security/test/csp/file_ignore_xfo.html^headers^
@@ -0,0 +1,3 @@
+Content-Security-Policy: frame-ancestors http://mochi.test:8888
+X-Frame-Options: deny
+Cache-Control: no-cache
diff --git a/dom/security/test/csp/file_image_nonce.html b/dom/security/test/csp/file_image_nonce.html
new file mode 100644
index 000000000..5d57bb837
--- /dev/null
+++ b/dom/security/test/csp/file_image_nonce.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset='utf-8'>
+ <title>Bug 1355801: Nonce should not apply to images</title>
+ </head>
+<body>
+
+<img id='matchingNonce' src='http://mochi.test:8888/tests/image/test/mochitest/blue.png?a' nonce='abc'></img>
+<img id='nonMatchingNonce' src='http://mochi.test:8888/tests/image/test/mochitest/blue.png?b' nonce='bca'></img>
+<img id='noNonce' src='http://mochi.test:8888/tests/image/test/mochitest/blue.png?c'></img>
+
+<script type='application/javascript'>
+ var matchingNonce = document.getElementById('matchingNonce');
+ matchingNonce.onload = function(e) {
+ window.parent.postMessage({result: 'img-with-matching-nonce-loaded'}, '*');
+ };
+ matchingNonce.onerror = function(e) {
+ window.parent.postMessage({result: 'img-with-matching-nonce-blocked'}, '*');
+ }
+
+ var nonMatchingNonce = document.getElementById('nonMatchingNonce');
+ nonMatchingNonce.onload = function(e) {
+ window.parent.postMessage({result: 'img-with_non-matching-nonce-loaded'}, '*');
+ };
+ nonMatchingNonce.onerror = function(e) {
+ window.parent.postMessage({result: 'img-with_non-matching-nonce-blocked'}, '*');
+ }
+
+ var noNonce = document.getElementById('noNonce');
+ noNonce.onload = function(e) {
+ window.parent.postMessage({result: 'img-without-nonce-loaded'}, '*');
+ };
+ noNonce.onerror = function(e) {
+ window.parent.postMessage({result: 'img-without-nonce-blocked'}, '*');
+ }
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_image_nonce.html^headers^ b/dom/security/test/csp/file_image_nonce.html^headers^
new file mode 100644
index 000000000..0d63558c4
--- /dev/null
+++ b/dom/security/test/csp/file_image_nonce.html^headers^
@@ -0,0 +1,2 @@
+Content-Security-Policy: img-src 'nonce-abc';
+Cache-Control: no-cache
diff --git a/dom/security/test/csp/file_punycode_host_src.js b/dom/security/test/csp/file_punycode_host_src.js
new file mode 100644
index 000000000..3505faf70
--- /dev/null
+++ b/dom/security/test/csp/file_punycode_host_src.js
@@ -0,0 +1,2 @@
+const LOADED = true;
+parent.postMessage({result: 'script-allowed'}, "*"); \ No newline at end of file
diff --git a/dom/security/test/csp/file_punycode_host_src.sjs b/dom/security/test/csp/file_punycode_host_src.sjs
new file mode 100644
index 000000000..3189cc063
--- /dev/null
+++ b/dom/security/test/csp/file_punycode_host_src.sjs
@@ -0,0 +1,45 @@
+// custom *.sjs for Bug 1224225
+// Punycode in CSP host sources
+
+const HTML_PART1 =
+ "<!DOCTYPE HTML>" +
+ "<html><head><meta charset=\"utf-8\">" +
+ "<title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>" +
+ "</head>" +
+ "<body>" +
+ "<script id='script' src='";
+
+const TESTCASE1 = "http://sub2.ält.example.org/";
+const TESTCASE2 = "http://sub2.xn--lt-uia.example.org/"
+
+const HTML_PART2 = "tests/dom/security/test/csp/file_punycode_host_src.js'></script>" +
+ "</body>" +
+ "</html>";
+
+function handleRequest(request, response)
+{
+ // avoid confusing cache behaviors
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/html", false);
+
+ Components.utils.importGlobalProperties(["URLSearchParams"]);
+ const query = new URLSearchParams(request.queryString);
+
+
+ if (query.get("csp")) {
+ response.setHeader("Content-Security-Policy", query.get("csp"), false);
+ }
+ if (query.get("action") == "script-unicode-csp-punycode") {
+ response.write(HTML_PART1 + TESTCASE1 + HTML_PART2);
+ return
+ }
+ if (query.get("action") == "script-punycode-csp-punycode") {
+ response.write(HTML_PART1 + TESTCASE2 + HTML_PART2);
+ return
+ }
+
+
+ // we should never get here, but just in case
+ // return something unexpected
+ response.write("do'h");
+}
diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html b/dom/security/test/csp/file_ro_ignore_xfo.html
new file mode 100644
index 000000000..85e7f0092
--- /dev/null
+++ b/dom/security/test/csp/file_ro_ignore_xfo.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title>
+</head>
+<body>
+<div id="cspmessage">Ignoring XFO because of CSP_RO</div>
+</body>
+</html> \ No newline at end of file
diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^
new file mode 100644
index 000000000..ab8366f06
--- /dev/null
+++ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^
@@ -0,0 +1,3 @@
+Content-Security-Policy-Report-Only: frame-ancestors http://mochi.test:8888
+X-Frame-Options: deny
+Cache-Control: no-cache
diff --git a/dom/security/test/csp/file_spawn_service_worker.js b/dom/security/test/csp/file_spawn_service_worker.js
new file mode 100644
index 000000000..b262fa10a
--- /dev/null
+++ b/dom/security/test/csp/file_spawn_service_worker.js
@@ -0,0 +1 @@
+// dummy file
diff --git a/dom/security/test/csp/file_spawn_shared_worker.js b/dom/security/test/csp/file_spawn_shared_worker.js
new file mode 100644
index 000000000..00063bc5c
--- /dev/null
+++ b/dom/security/test/csp/file_spawn_shared_worker.js
@@ -0,0 +1,7 @@
+onconnect = function(e) {
+ var port = e.ports[0];
+ port.addEventListener("message", function(e) {
+ port.postMessage("shared worker is executing");
+ });
+ port.start();
+}
diff --git a/dom/security/test/csp/file_spawn_worker.js b/dom/security/test/csp/file_spawn_worker.js
new file mode 100644
index 000000000..acde7408c
--- /dev/null
+++ b/dom/security/test/csp/file_spawn_worker.js
@@ -0,0 +1 @@
+postMessage("worker is executing");
diff --git a/dom/security/test/csp/file_upgrade_insecure_navigation.sjs b/dom/security/test/csp/file_upgrade_insecure_navigation.sjs
new file mode 100644
index 000000000..51afa39bf
--- /dev/null
+++ b/dom/security/test/csp/file_upgrade_insecure_navigation.sjs
@@ -0,0 +1,79 @@
+// Custom *.sjs file specifically for the needs of
+// https://bugzilla.mozilla.org/show_bug.cgi?id=1271173
+
+"use strict";
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+
+const TEST_NAVIGATIONAL_UPGRADE = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body>
+ <a href="http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_navigation.sjs?action=framenav" id="testlink">clickme</a>
+ <script type="text/javascript">
+ // before navigating the current frame we open the window and check that uir applies
+ var myWin = window.open("http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_navigation.sjs?action=docnav");
+
+ window.addEventListener("message", receiveMessage, false);
+ function receiveMessage(event) {
+ myWin.close();
+ var link = document.getElementById('testlink');
+ link.click();
+ }
+ </script>
+ </body>
+ </html>`;
+
+const FRAME_NAV = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body>
+ <script type="text/javascript">
+ parent.postMessage({result: document.documentURI}, "*");
+ </script>
+ </body>
+ </html>`;
+
+const DOC_NAV = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body>
+ <script type="text/javascript">
+ // call back to the main testpage signaling whether the upgraded succeeded
+ window.opener.parent.postMessage({result: document.documentURI}, "*");
+ // let the opener (iframe) now that we can now close the window and move on with the test.
+ window.opener.postMessage({result: "readyToMoveOn"}, "*");
+ </script>
+ </body>
+ </html>`;
+
+function handleRequest(request, response) {
+ const query = new URLSearchParams(request.queryString);
+
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/html", false);
+ if (query.get("csp")) {
+ response.setHeader("Content-Security-Policy", query.get("csp"), false);
+ }
+
+ if (query.get("action") === "perform_navigation") {
+ response.write(TEST_NAVIGATIONAL_UPGRADE);
+ return;
+ }
+
+ if (query.get("action") === "framenav") {
+ response.write(FRAME_NAV);
+ return;
+ }
+
+ if (query.get("action") === "docnav") {
+ response.write(DOC_NAV);
+ return;
+ }
+
+ // we should never get here, but just in case
+ // return something unexpected
+ response.write("do'h");
+}
diff --git a/dom/security/test/csp/file_websocket_explicit.html b/dom/security/test/csp/file_websocket_explicit.html
new file mode 100644
index 000000000..51462ab74
--- /dev/null
+++ b/dom/security/test/csp/file_websocket_explicit.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
+ <meta http-equiv="Content-Security-Policy" content="connect-src ws:">
+</head>
+<body>
+ <script type="application/javascript">
+ /* load socket using ws */
+ var wsSocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wsSocket.onopen = function(e) {
+ window.parent.postMessage({result: "explicit-ws-loaded"}, "*");
+ wsSocket.close();
+ };
+ wsSocket.onerror = function(e) {
+ window.parent.postMessage({result: "explicit-ws-blocked"}, "*");
+ };
+
+ /* load socket using wss */
+ var wssSocket = new WebSocket("wss://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wssSocket.onopen = function(e) {
+ window.parent.postMessage({result: "explicit-wss-loaded"}, "*");
+ wssSocket.close();
+ };
+ wssSocket.onerror = function(e) {
+ window.parent.postMessage({result: "explicit-wss-blocked"}, "*");
+ };
+ </script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_websocket_self.html b/dom/security/test/csp/file_websocket_self.html
new file mode 100644
index 000000000..3ff5f0558
--- /dev/null
+++ b/dom/security/test/csp/file_websocket_self.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
+ <meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
+</head>
+<body>
+ <script type="application/javascript">
+ /* load socket using ws */
+ var wsSocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wsSocket.onopen = function(e) {
+ window.parent.postMessage({result: "self-ws-loaded"}, "*");
+ wsSocket.close();
+ };
+ wsSocket.onerror = function(e) {
+ window.parent.postMessage({result: "self-ws-blocked"}, "*");
+ };
+
+ /* load socket using wss */
+ var wssSocket = new WebSocket("wss://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wssSocket.onopen = function(e) {
+ window.parent.postMessage({result: "self-wss-loaded"}, "*");
+ wssSocket.close();
+ };
+ wssSocket.onerror = function(e) {
+ window.parent.postMessage({result: "self-wss-blocked"}, "*");
+ };
+ </script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_websocket_self_wsh.py b/dom/security/test/csp/file_websocket_self_wsh.py
new file mode 100644
index 000000000..5fe508a91
--- /dev/null
+++ b/dom/security/test/csp/file_websocket_self_wsh.py
@@ -0,0 +1,7 @@
+from mod_pywebsocket import msgutil
+
+def web_socket_do_extra_handshake(request):
+ pass
+
+def web_socket_transfer_data(request):
+ pass
diff --git a/dom/security/test/csp/file_worker_src.js b/dom/security/test/csp/file_worker_src.js
new file mode 100644
index 000000000..ad3ade6a6
--- /dev/null
+++ b/dom/security/test/csp/file_worker_src.js
@@ -0,0 +1,52 @@
+
+let myWorker = new Worker("file_spawn_worker.js");
+myWorker.onmessage = function(event) {
+ parent.postMessage({
+ result: "worker-allowed",
+ href: document.location.href,
+ }, "*");
+}
+myWorker.onerror = function(event) {
+ parent.postMessage({
+ result: "worker-blocked",
+ href: document.location.href,
+ }, "*");
+}
+
+// --------------------------------------------
+
+var mySharedWorker = new SharedWorker('file_spawn_shared_worker.js');
+mySharedWorker.port.onmessage = function(ev) {
+ parent.postMessage({
+ result: "shared-worker-allowed",
+ href: document.location.href,
+ }, "*");
+}
+mySharedWorker.onerror = function(evt) {
+ evt.preventDefault();
+ parent.postMessage({
+ result: "shared-worker-blocked",
+ href: document.location.href,
+ }, "*");
+}
+mySharedWorker.port.start();
+mySharedWorker.port.postMessage('foo');
+
+// --------------------------------------------
+
+navigator.serviceWorker.register('file_spawn_service_worker.js')
+.then(function(reg) {
+ // registration worked
+ reg.unregister().then(function() {
+ parent.postMessage({
+ result: "service-worker-allowed",
+ href: document.location.href,
+ }, "*");
+ });
+}).catch(function(error) {
+ // registration failed
+ parent.postMessage({
+ result: "service-worker-blocked",
+ href: document.location.href,
+ }, "*");
+});
diff --git a/dom/security/test/csp/file_worker_src_child_governs.html b/dom/security/test/csp/file_worker_src_child_governs.html
new file mode 100644
index 000000000..ca8a683aa
--- /dev/null
+++ b/dom/security/test/csp/file_worker_src_child_governs.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="child-src https://example.com; script-src 'nonce-foo'">";
+</head>
+<body>
+<script type="text/javascript" src="file_worker_src.js" nonce="foo"></script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_worker_src_script_governs.html b/dom/security/test/csp/file_worker_src_script_governs.html
new file mode 100644
index 000000000..0385fee57
--- /dev/null
+++ b/dom/security/test/csp/file_worker_src_script_governs.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-foo' https://example.com">";
+</head>
+<body>
+<script type="text/javascript" src="file_worker_src.js" nonce="foo"></script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_worker_src_worker_governs.html b/dom/security/test/csp/file_worker_src_worker_governs.html
new file mode 100644
index 000000000..93c8f6122
--- /dev/null
+++ b/dom/security/test/csp/file_worker_src_worker_governs.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="worker-src https://example.com; child-src 'none'; script-src 'nonce-foo'">";
+</head>
+<body>
+<script type="text/javascript" src="file_worker_src.js" nonce="foo"></script>
+</body>
+</html>
diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini
index 8add999c3..33b112020 100644
--- a/dom/security/test/csp/mochitest.ini
+++ b/dom/security/test/csp/mochitest.ini
@@ -91,6 +91,8 @@ support-files =
file_bug941404.html
file_bug941404_xhr.html
file_bug941404_xhr.html^headers^
+ file_frame_ancestors_ro.html
+ file_frame_ancestors_ro.html^headers^
file_hash_source.html
file_dual_header_testserver.sjs
file_hash_source.html^headers^
@@ -206,6 +208,18 @@ support-files =
file_iframe_srcdoc.sjs
file_iframe_sandbox_srcdoc.html
file_iframe_sandbox_srcdoc.html^headers^
+ file_ignore_xfo.html
+ file_ignore_xfo.html^headers^
+ file_ro_ignore_xfo.html
+ file_ro_ignore_xfo.html^headers^
+ file_upgrade_insecure_navigation.sjs
+ file_image_nonce.html
+ file_image_nonce.html^headers^
+ file_punycode_host_src.sjs
+ file_punycode_host_src.js
+ file_websocket_self.html
+ file_websocket_explicit.html
+ file_websocket_self_wsh.py
[test_base-uri.html]
[test_blob_data_schemes.html]
@@ -228,6 +242,7 @@ skip-if = toolkit == 'android' # Times out, not sure why (bug 1008445)
[test_bug910139.html]
[test_bug909029.html]
[test_bug1229639.html]
+[test_frame_ancestors_ro.html]
[test_policyuri_regression_from_multipolicy.html]
[test_nonce_source.html]
[test_bug941404.html]
@@ -292,9 +307,30 @@ tags = mcb
[test_strict_dynamic.html]
[test_strict_dynamic_parser_inserted.html]
[test_strict_dynamic_default_src.html]
+[test_upgrade_insecure_navigation.html]
[test_iframe_sandbox_srcdoc.html]
[test_iframe_srcdoc.html]
[test_sandbox_allow_scripts.html]
support-files =
file_sandbox_allow_scripts.html
file_sandbox_allow_scripts.html^headers^
+[test_ignore_xfo.html]
+[test_image_nonce.html]
+[test_punycode_host_src.html]
+[test_websocket_self.html]
+skip-if = toolkit == 'android'
+[test_worker_src.html]
+support-files =
+ file_worker_src_worker_governs.html
+ file_worker_src_child_governs.html
+ file_worker_src_script_governs.html
+ file_worker_src.js
+ file_spawn_worker.js
+ file_spawn_shared_worker.js
+ file_spawn_service_worker.js
+[test_frame_src.html]
+support-files =
+ file_frame_src_frame_governs.html
+ file_frame_src_child_governs.html
+ file_frame_src.js
+ file_frame_src_inner.html
diff --git a/dom/security/test/csp/test_child-src_worker.html b/dom/security/test/csp/test_child-src_worker.html
index 7dcbd03f6..ea9e7b28e 100644
--- a/dom/security/test/csp/test_child-src_worker.html
+++ b/dom/security/test/csp/test_child-src_worker.html
@@ -83,19 +83,19 @@
id: "script-src-worker",
file: WORKER_TEST_FILE,
result : "blocked",
- policy : "default-src 'none'; script-src 'self' 'unsafe-inline'"
+ policy : "default-src 'none'; script-src https://www.example.org 'unsafe-inline'"
},
'script-src-service_worker': {
id: "script-src-service_worker",
file: SERVICE_WORKER_TEST_FILE,
result : "blocked",
- policy : "default-src 'none'; script-src 'self' 'unsafe-inline'"
+ policy : "default-src 'none'; script-src https://www.example.org 'unsafe-inline'"
},
'script-src-self-shared_worker': {
id: "script-src-self-shared_worker",
file: SHARED_WORKER_TEST_FILE,
result : "blocked",
- policy : "default-src 'none'; script-src 'self' 'unsafe-inline'"
+ policy : "default-src 'none'; script-src https://www.example.org 'unsafe-inline'"
},
};
diff --git a/dom/security/test/csp/test_frame_ancestors_ro.html b/dom/security/test/csp/test_frame_ancestors_ro.html
new file mode 100644
index 000000000..90f68e25e
--- /dev/null
+++ b/dom/security/test/csp/test_frame_ancestors_ro.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for frame-ancestors support in Content-Security-Policy-Report-Only</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width: 100%" id="cspframe"></iframe>
+<script type="text/javascript">
+const docUri = "http://mochi.test:8888/tests/dom/security/test/csp/file_frame_ancestors_ro.html";
+const frame = document.getElementById("cspframe");
+
+let testResults = {
+ reportFired: false,
+ frameLoaded: false
+};
+
+function checkResults(reportObj) {
+ let cspReport = reportObj["csp-report"];
+ is(cspReport["document-uri"], docUri, "Incorrect document-uri");
+
+ // we can not test for the whole referrer since it includes platform specific information
+ is(cspReport["referrer"], document.location.toString(), "Incorrect referrer");
+ is(cspReport["blocked-uri"], document.location.toString(), "Incorrect blocked-uri");
+ is(cspReport["violated-directive"], "frame-ancestors 'none'", "Incorrect violated-directive");
+ is(cspReport["original-policy"], "frame-ancestors 'none'; report-uri http://mochi.test:8888/foo.sjs", "Incorrect original-policy");
+ testResults.reportFired = true;
+}
+
+let chromeScriptUrl = SimpleTest.getTestFileURL("file_report_chromescript.js");
+let script = SpecialPowers.loadChromeScript(chromeScriptUrl);
+
+script.addMessageListener('opening-request-completed', function ml(msg) {
+ if (msg.error) {
+ ok(false, "Could not query report (exception: " + msg.error + ")");
+ } else {
+ try {
+ let reportObj = JSON.parse(msg.report);
+ // test for the proper values in the report object
+ checkResults(reportObj);
+ } catch (e) {
+ ok(false, "Error verifying report object (exception: " + e + ")");
+ }
+ }
+
+ script.removeMessageListener('opening-request-completed', ml);
+ script.sendAsyncMessage("finish");
+ checkTestResults();
+});
+
+frame.addEventListener( 'load', () => {
+ // Make sure the frame is still loaded
+ testResults.frameLoaded = true;
+ checkTestResults()
+} );
+
+function checkTestResults() {
+ if( testResults.reportFired && testResults.frameLoaded ) {
+ SimpleTest.finish();
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+frame.src = docUri;
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_frame_src.html b/dom/security/test/csp/test_frame_src.html
new file mode 100644
index 000000000..07de90cfa
--- /dev/null
+++ b/dom/security/test/csp/test_frame_src.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1302667 - Test frame-src</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+/* Description of the test:
+ * We load a page inlcuding a frame a CSP of:
+ * >> frame-src https://example.com; child-src 'none'
+ * and make sure that frame-src governs frames correctly. In addition,
+ * we make sure that child-src is discarded in case frame-src is specified.
+ */
+
+const ORIGIN_1 = "https://example.com/tests/dom/security/test/csp/";
+const ORIGIN_2 = "https://test1.example.com/tests/dom/security/test/csp/";
+
+let TESTS = [
+ // frame-src tests
+ ORIGIN_1 + "file_frame_src_frame_governs.html",
+ ORIGIN_2 + "file_frame_src_frame_governs.html",
+ // child-src tests
+ ORIGIN_1 + "file_frame_src_child_governs.html",
+ ORIGIN_2 + "file_frame_src_child_governs.html",
+];
+
+let testIndex = 0;
+
+function checkFinish() {
+ if (testIndex >= TESTS.length) {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+ return;
+ }
+ runNextTest();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ let href = event.data.href;
+ let result = event.data.result;
+
+ if (href.startsWith("https://example.com")) {
+ if (result == "frame-allowed") {
+ ok(true, "allowing frame from https://example.com (" + result + ")");
+ }
+ else {
+ ok(false, "blocking frame from https://example.com (" + result + ")");
+ }
+ }
+ else if (href.startsWith("https://test1.example.com")) {
+ if (result == "frame-blocked") {
+ ok(true, "blocking frame from https://test1.example.com (" + result + ")");
+ }
+ else {
+ ok(false, "allowing frame from https://test1.example.com (" + result + ")");
+ }
+ }
+ else {
+ // sanity check, we should never enter that branch, bust just in case...
+ ok(false, "unexpected result: " + result);
+ }
+ checkFinish();
+}
+
+function runNextTest() {
+ document.getElementById("testframe").src = TESTS[testIndex];
+ testIndex++;
+}
+
+// fire up the tests
+runNextTest();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_ignore_xfo.html b/dom/security/test/csp/test_ignore_xfo.html
new file mode 100644
index 000000000..fb3aadc6c
--- /dev/null
+++ b/dom/security/test/csp/test_ignore_xfo.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="csp_testframe"></iframe>
+<iframe style="width:100%;" id="csp_ro_testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/*
+ * We load two frames using:
+ * x-frame-options: deny
+ * where the first frame uses a csp and the second a csp_ro including frame-ancestors.
+ * We make sure that xfo is ignored for regular csp but not for csp_ro.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var testcounter = 0;
+function checkFinished() {
+ testcounter++;
+ if (testcounter < 2) {
+ return;
+ }
+ SimpleTest.finish();
+}
+
+// 1) test XFO with CSP
+var csp_testframe = document.getElementById("csp_testframe");
+csp_testframe.onload = function() {
+ var msg = csp_testframe.contentWindow.document.getElementById("cspmessage");
+ is(msg.innerHTML, "Ignoring XFO because of CSP", "Loading frame with with XFO and CSP");
+ checkFinished();
+}
+csp_testframe.onerror = function() {
+ ok(false, "sanity: should not fire onerror for csp_testframe");
+}
+csp_testframe.src = "file_ignore_xfo.html";
+
+// 2) test XFO with CSP_RO
+var csp_ro_testframe = document.getElementById("csp_ro_testframe");
+csp_ro_testframe.onload = function() {
+ var msg = csp_ro_testframe.contentWindow.document.getElementById("cspmessage");
+ is(msg, null, "Blocking frame with with XFO and CSP_RO");
+ checkFinished();
+}
+csp_ro_testframe.onerror = function() {
+ ok(false, "sanity: should not fire onerror for csp_ro_testframe");
+}
+csp_ro_testframe.src = "file_ro_ignore_xfo.html";
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_image_nonce.html b/dom/security/test/csp/test_image_nonce.html
new file mode 100644
index 000000000..ff6d636b6
--- /dev/null
+++ b/dom/security/test/csp/test_image_nonce.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1139297 - Implement CSP upgrade-insecure-requests directive</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load three images: (a) with a matching nonce,
+ (b) with a non matching nonce,
+ * (c) with no nonce
+ * and make sure that all three images get blocked because
+ * "img-src nonce-bla" should not allow an image load, not
+ * even if the nonce matches*.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var counter = 0;
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+function checkResults(aResult) {
+ counter++;
+ if (aResult === "img-with-matching-nonce-blocked" ||
+ aResult === "img-with_non-matching-nonce-blocked" ||
+ aResult === "img-without-nonce-blocked") {
+ ok (true, "correct result for: " + aResult);
+ }
+ else {
+ ok(false, "unexpected result: " + aResult + "\n\n");
+ }
+ if (counter < 3) {
+ return;
+ }
+ finishTest();
+}
+
+// a postMessage handler that is used by sandboxed iframes without
+// 'allow-same-origin' to bubble up results back to this main page.
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ checkResults(event.data.result);
+}
+
+document.getElementById("testframe").src = "file_image_nonce.html";
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_punycode_host_src.html b/dom/security/test/csp/test_punycode_host_src.html
new file mode 100644
index 000000000..8d891725c
--- /dev/null
+++ b/dom/security/test/csp/test_punycode_host_src.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load scripts within an iframe and make sure that the
+ * CSP matching is same for punycode domain names as well as IDNA.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+
+var curTest;
+var counter = -1;
+
+const tests = [
+ { // test 1
+ description: "loads script as sub2.ält.example.org, but whitelist in CSP as sub2.xn--lt-uia.example.org",
+ action: "script-unicode-csp-punycode",
+ csp: "script-src http://sub2.xn--lt-uia.example.org;",
+ expected: "script-allowed",
+
+ },
+ { // test 2
+ description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
+ action: "script-punycode-csp-punycode",
+ csp: "script-src http://sub2.xn--lt-uia.example.org;",
+ expected: "script-allowed",
+
+ },
+ { // test 3
+ description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
+ action: "script-punycode-csp-punycode",
+ csp: "script-src *.xn--lt-uia.example.org;",
+ expected: "script-allowed",
+
+ },
+
+];
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+function checkResults(result) {
+ is(result, curTest.expected, curTest.description);
+ loadNextTest();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ checkResults(event.data.result);
+}
+
+function loadNextTest() {
+ counter++;
+ if (counter == tests.length) {
+ finishTest();
+ return;
+ }
+ curTest = tests[counter];
+ var testframe = document.getElementById("testframe");
+ testframe.src = `file_punycode_host_src.sjs?action=${curTest.action}&csp=${curTest.csp}`;
+}
+
+loadNextTest();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_upgrade_insecure_navigation.html b/dom/security/test/csp/test_upgrade_insecure_navigation.html
new file mode 100644
index 000000000..db6a6a1be
--- /dev/null
+++ b/dom/security/test/csp/test_upgrade_insecure_navigation.html
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Bug 1271173 - Missing spec on Upgrade Insecure Requests(Navigational Upgrades) </title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+<iframe style="width:100%;" id="sandboxedtestframe"
+ sandbox="allow-scripts allow-top-navigation allow-same-origin allow-pointer-lock allow-popups"></iframe>
+
+<script class="testbody" type="text/javascript">
+/*
+ * Description of the test:
+ * We load a page into an iframe that performs a navigational request.
+ * We make sure that upgrade-insecure-requests applies and the page
+ * gets upgraded to https if same origin.
+ * Please note that uir only applies to sandboxed iframes if
+ * the value 'allow-same-origin' is specified.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var tests = [
+ {
+ csp: "upgrade-insecure-requests;",
+ result: "https",
+ origin: "http://example.com",
+ desc: "upgrade-insecure-requests same origin should upgrade"
+ },
+ {
+ csp: "",
+ result: "http",
+ origin: "http://example.com",
+ desc: "No upgrade-insecure-requests same origin should not upgrade"
+ },
+ {
+ csp: "upgrade-insecure-requests;",
+ result: "http",
+ origin: "http://mochi.test:8888",
+ desc: "upgrade-insecure-requests cross origin should not upgrade"
+ },
+ {
+ csp: "",
+ result: "http",
+ origin: "http://mochi.test:8888",
+ desc: "No upgrade-insecure-requests cross origin should not upgrade"
+ },
+];
+
+// initializing to -1 so we start at index 0 when we start the test
+var counter = -1;
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage, false);
+ SimpleTest.finish();
+}
+
+var subtests = 0;
+
+window.addEventListener("message", receiveMessage, false);
+function receiveMessage(event) {
+ var result = event.data.result;
+ // query the scheme from the URL before comparing the result
+ var scheme = result.substring(0, result.indexOf(":"));
+ is(scheme, tests[counter].result, tests[counter].desc);
+
+ // @hardcoded 4:
+ // each test run contains of two subtests (frame and top-level)
+ // and we load each test into a regular iframe and into a
+ // sandboxed iframe. only move on to the next test once all
+ // four results from the subtests have bubbled up.
+ subtests++;
+ if (subtests != 4) {
+ return;
+ }
+ subtests = 0;
+ loadNextTest();
+}
+
+function loadNextTest() {
+ counter++;
+ if (counter == tests.length) {
+ finishTest();
+ return;
+ }
+
+ var src = tests[counter].origin;
+ src += "/tests/dom/security/test/csp/file_upgrade_insecure_navigation.sjs";
+ src += "?csp=" + escape(tests[counter].csp);
+ src += "&action=perform_navigation";
+ document.getElementById("testframe").src = src;
+ document.getElementById("sandboxedtestframe").src = src;
+}
+
+// start running the tests
+loadNextTest();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_websocket_self.html b/dom/security/test/csp/test_websocket_self.html
new file mode 100644
index 000000000..a03c32704
--- /dev/null
+++ b/dom/security/test/csp/test_websocket_self.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="test_ws_self_frame"></iframe>
+<iframe style="width:100%;" id="test_ws_explicit_frame"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load an iframe using connect-src 'self' and one
+ * iframe using connect-src ws: and make
+ * sure that in both cases ws: as well as wss: is allowed to load.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+const TOTAL_TESTS = 4;
+var counter = 0;
+
+function checkResults(result) {
+ counter++;
+ if (result === "self-ws-loaded" || result === "self-wss-loaded" ||
+ result === "explicit-ws-loaded" || result === "explicit-wss-loaded") {
+ ok(true, "Evaluating: " + result);
+ }
+ else {
+ ok(false, "Evaluating: " + result);
+ }
+ if (counter < TOTAL_TESTS) {
+ return;
+ }
+ finishTest();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ checkResults(event.data.result);
+}
+
+const HOST = "http://example.com/tests/dom/security/test/csp/";
+var test_ws_self_frame = document.getElementById("test_ws_self_frame");
+test_ws_self_frame.src = HOST + "file_websocket_self.html";
+
+var test_ws_explicit_frame = document.getElementById("test_ws_explicit_frame");
+test_ws_explicit_frame.src = HOST + "file_websocket_explicit.html";
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_worker_src.html b/dom/security/test/csp/test_worker_src.html
new file mode 100644
index 000000000..3f2b44c9f
--- /dev/null
+++ b/dom/security/test/csp/test_worker_src.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1302667 - Test worker-src</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="worker-testframe"></iframe>
+<iframe style="width:100%;" id="child-testframe"></iframe>
+<iframe style="width:100%;" id="script-testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+/* Description of the test:
+ * We load a page inlcuding a worker, a shared worker as well as a
+ * service worker with a CSP of:
+ * >> worker-src https://example.com; child-src 'none'; script-src 'nonce-foo'
+ * and make sure that worker-src governs these three kinds of workers correctly.
+ * In addition, we make sure that child-src as well as script-src is discarded
+ * in case worker-src is specified. Ideally we would use "script-src 'none'" but
+ * we have to whitelist the actual script that spawns the workers, hence the nonce.
+ */
+
+let testRuns = 0;
+let messageCounter = 0;
+let numberSubTests = 9; // 3 workers * 3 frames = 9
+
+function checkFinish() {
+ messageCounter = 0;
+ if (testRuns == 0) {
+ testRuns++;
+ runTests("https://test1.example.com/tests/dom/security/test/csp/")
+ return;
+ }
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ let href = event.data.href;
+ let result = event.data.result;
+
+ if (href.startsWith("https://example.com")) {
+ if (result == "worker-allowed" ||
+ result == "shared-worker-allowed" ||
+ result == "service-worker-allowed") {
+ ok(true, "allowing worker from https://example.com (" + result + ")");
+ }
+ else {
+ ok(false, "blocking worker from https://example.com (" + result + ")");
+ }
+ }
+ else if (href.startsWith("https://test1.example.com")) {
+ if (result == "worker-blocked" ||
+ result == "shared-worker-blocked" ||
+ result == "service-worker-blocked") {
+ ok(true, "blocking worker from https://test1.example.com (" + result + ")");
+ }
+ else {
+ ok(false, "allowing worker from https://test1.example.com (" + result + ")");
+ }
+ }
+ else {
+ // sanity check, we should never enter that branch, bust just in case...
+ ok(false, "unexpected result: " + result);
+ }
+ messageCounter++;
+ if (messageCounter < numberSubTests) {
+ return;
+ }
+ checkFinish();
+}
+
+function runTests(aPath) {
+ document.getElementById("worker-testframe").src = aPath + "file_worker_src_worker_governs.html";
+ document.getElementById("child-testframe").src = aPath + "file_worker_src_child_governs.html";
+ document.getElementById("script-testframe").src = aPath + "file_worker_src_script_governs.html";
+}
+
+SpecialPowers.pushPrefEnv({"set": [
+ ["dom.serviceWorkers.enabled", true],
+ ["dom.serviceWorkers.testing.enabled", true],
+]}, function() {
+ runTests("https://example.com/tests/dom/security/test/csp/");
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/browser.ini b/dom/security/test/general/browser.ini
new file mode 100644
index 000000000..b00baa95d
--- /dev/null
+++ b/dom/security/test/general/browser.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+[browser_test_toplevel_data_navigations.js]
+support-files =
+ file_toplevel_data_navigations.sjs
+ file_toplevel_data_meta_redirect.html
+[browser_test_data_download.js]
+support-files =
+ file_data_download.html
+[browser_test_data_text_csv.js]
+support-files =
+ file_data_text_csv.html
+[browser_test_view_image_data_navigation.js]
+support-files =
+ file_view_image_data_navigation.html
diff --git a/dom/security/test/general/browser_test_data_download.js b/dom/security/test/general/browser_test_data_download.js
new file mode 100644
index 000000000..1ee8d5844
--- /dev/null
+++ b/dom/security/test/general/browser_test_data_download.js
@@ -0,0 +1,37 @@
+"use strict";
+
+const kTestPath = getRootDirectory(gTestPath)
+ .replace("chrome://mochitests/content", "http://example.com")
+const kTestURI = kTestPath + "file_data_download.html";
+
+function addWindowListener(aURL, aCallback) {
+ Services.wm.addListener({
+ onOpenWindow(aXULWindow) {
+ info("window opened, waiting for focus");
+ Services.wm.removeListener(this);
+ var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+ waitForFocus(function() {
+ is(domwindow.document.location.href, aURL, "should have seen the right window open");
+ aCallback(domwindow);
+ }, domwindow);
+ },
+ onCloseWindow(aXULWindow) { },
+ onWindowTitleChange(aXULWindow, aNewTitle) { }
+ });
+}
+
+function test() {
+ waitForExplicitFinish();
+ Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
+ registerCleanupFunction(function() {
+ Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
+ });
+ addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) {
+ is(win.document.getElementById("location").value, "data-foo.html",
+ "file name of download should match");
+ win.close();
+ finish();
+ });
+ gBrowser.loadURI(kTestURI);
+}
diff --git a/dom/security/test/general/browser_test_data_text_csv.js b/dom/security/test/general/browser_test_data_text_csv.js
new file mode 100644
index 000000000..c45e40cc2
--- /dev/null
+++ b/dom/security/test/general/browser_test_data_text_csv.js
@@ -0,0 +1,37 @@
+"use strict";
+
+const kTestPath = getRootDirectory(gTestPath)
+ .replace("chrome://mochitests/content", "http://example.com")
+const kTestURI = kTestPath + "file_data_text_csv.html";
+
+function addWindowListener(aURL, aCallback) {
+ Services.wm.addListener({
+ onOpenWindow(aXULWindow) {
+ info("window opened, waiting for focus");
+ Services.wm.removeListener(this);
+ var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+ waitForFocus(function() {
+ is(domwindow.document.location.href, aURL, "should have seen the right window open");
+ aCallback(domwindow);
+ }, domwindow);
+ },
+ onCloseWindow(aXULWindow) { },
+ onWindowTitleChange(aXULWindow, aNewTitle) { }
+ });
+}
+
+function test() {
+ waitForExplicitFinish();
+ Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
+ registerCleanupFunction(function() {
+ Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
+ });
+ addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) {
+ is(win.document.getElementById("location").value, "text/csv;foo,bar,foobar",
+ "file name of download should match");
+ win.close();
+ finish();
+ });
+ gBrowser.loadURI(kTestURI);
+}
diff --git a/dom/security/test/general/browser_test_toplevel_data_navigations.js b/dom/security/test/general/browser_test_toplevel_data_navigations.js
new file mode 100644
index 000000000..a13a6350e
--- /dev/null
+++ b/dom/security/test/general/browser_test_toplevel_data_navigations.js
@@ -0,0 +1,54 @@
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+
+"use strict";
+
+const kDataBody = "toplevel navigation to data: URI allowed";
+const kDataURI = "data:text/html,<body>" + kDataBody + "</body>";
+const kTestPath = getRootDirectory(gTestPath)
+ .replace("chrome://mochitests/content", "http://example.com")
+const kRedirectURI = kTestPath + "file_toplevel_data_navigations.sjs";
+const kMetaRedirectURI = kTestPath + "file_toplevel_data_meta_redirect.html";
+
+add_task(async function test_nav_data_uri() {
+ await SpecialPowers.pushPrefEnv({
+ "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]],
+ });
+ await BrowserTestUtils.withNewTab(kDataURI, async function(browser) {
+ await ContentTask.spawn(gBrowser.selectedBrowser, {kDataBody}, async function({kDataBody}) { // eslint-disable-line
+ is(content.document.body.innerHTML, kDataBody,
+ "data: URI navigation from system should be allowed");
+ });
+ });
+});
+
+add_task(async function test_nav_data_uri_redirect() {
+ await SpecialPowers.pushPrefEnv({
+ "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]],
+ });
+ let tab = BrowserTestUtils.addTab(gBrowser, kRedirectURI);
+ registerCleanupFunction(async function() {
+ await BrowserTestUtils.removeTab(tab);
+ });
+ // wait to make sure data: URI did not load before checking that it got blocked
+ await new Promise(resolve => setTimeout(resolve, 500));
+ await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
+ is(content.document.body.innerHTML, "",
+ "data: URI navigation after server redirect should be blocked");
+ });
+});
+
+add_task(async function test_nav_data_uri_meta_redirect() {
+ await SpecialPowers.pushPrefEnv({
+ "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]],
+ });
+ let tab = BrowserTestUtils.addTab(gBrowser, kMetaRedirectURI);
+ registerCleanupFunction(async function() {
+ await BrowserTestUtils.removeTab(tab);
+ });
+ // wait to make sure data: URI did not load before checking that it got blocked
+ await new Promise(resolve => setTimeout(resolve, 500));
+ await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
+ is(content.document.body.innerHTML, "",
+ "data: URI navigation after meta redirect should be blocked");
+ });
+});
diff --git a/dom/security/test/general/browser_test_view_image_data_navigation.js b/dom/security/test/general/browser_test_view_image_data_navigation.js
new file mode 100644
index 000000000..22de35894
--- /dev/null
+++ b/dom/security/test/general/browser_test_view_image_data_navigation.js
@@ -0,0 +1,30 @@
+"use strict";
+
+const TEST_PAGE = getRootDirectory(gTestPath) + "file_view_image_data_navigation.html";
+
+add_task(async function test_principal_right_click_open_link_in_new_tab() {
+ await SpecialPowers.pushPrefEnv({
+ "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]],
+ });
+
+ await BrowserTestUtils.withNewTab(TEST_PAGE, async function(browser) {
+ let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, true);
+
+ // simulate right-click->view-image
+ BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
+ // These are operations that must be executed synchronously with the event.
+ document.getElementById("context-viewimage").doCommand();
+ event.target.hidePopup();
+ return true;
+ });
+ BrowserTestUtils.synthesizeMouseAtCenter("#testimage",
+ { type: "contextmenu", button: 2 },
+ gBrowser.selectedBrowser);
+ await loadPromise;
+
+ await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
+ ok(content.document.location.toString().startsWith("data:image/svg+xml;"),
+ "data:image/svg navigation allowed through right-click view-image")
+ });
+ });
+});
diff --git a/dom/security/test/general/file_block_toplevel_data_navigation.html b/dom/security/test/general/file_block_toplevel_data_navigation.html
new file mode 100644
index 000000000..5fbfdfdef
--- /dev/null
+++ b/dom/security/test/general/file_block_toplevel_data_navigation.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Toplevel data navigation</title>
+</head>
+<body>
+test1: clicking data: URI tries to navigate window<br/>
+<a id="testlink" href="data:text/html,<body>toplevel data: URI navigations should be blocked</body>">click me</a>
+<script>
+ document.getElementById('testlink').click();
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/file_block_toplevel_data_navigation2.html b/dom/security/test/general/file_block_toplevel_data_navigation2.html
new file mode 100644
index 000000000..e0308e1ae
--- /dev/null
+++ b/dom/security/test/general/file_block_toplevel_data_navigation2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Toplevel data navigation</title>
+</head>
+<body>
+test2: data: URI in iframe tries to window.open(data:, _blank);<br/>
+<iframe id="testFrame" src=""></iframe>
+<script>
+ let DATA_URI = `data:text/html,<body><script>
+ var win = window.open("data:text/html,<body>toplevel data: URI navigations should be blocked</body>", "_blank");
+ setTimeout(function () {
+ var result = win.document.body.innerHTML === "" ? "blocked" : "navigated";
+ parent.postMessage(result, "*");
+ win.close();
+ }, 1000);
+ <\/script></body>`;
+
+ window.addEventListener("message", receiveMessage);
+ function receiveMessage(event) {
+ window.removeEventListener("message", receiveMessage);
+ // propagate the information back to the caller
+ window.opener.postMessage(event.data, "*");
+ }
+ document.getElementById('testFrame').src = DATA_URI;
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/file_block_toplevel_data_navigation3.html b/dom/security/test/general/file_block_toplevel_data_navigation3.html
new file mode 100644
index 000000000..34aeddab3
--- /dev/null
+++ b/dom/security/test/general/file_block_toplevel_data_navigation3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Toplevel data navigation</title>
+</head>
+<body>
+test3: performing data: URI navigation through win.loc.href<br/>
+<script>
+ window.location.href = "data:text/html,<body>toplevel data: URI navigations should be blocked</body>";
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/file_block_toplevel_data_redirect.sjs b/dom/security/test/general/file_block_toplevel_data_redirect.sjs
new file mode 100644
index 000000000..64e294cab
--- /dev/null
+++ b/dom/security/test/general/file_block_toplevel_data_redirect.sjs
@@ -0,0 +1,14 @@
+// Custom *.sjs file specifically for the needs of Bug:
+// Bug 1394554 - Block toplevel data: URI navigations after redirect
+
+var DATA_URI =
+ "<body>toplevel data: URI navigations after redirect should be blocked</body>";
+
+function handleRequest(request, response)
+{
+ // avoid confusing cache behaviors
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ response.setStatusLine("1.1", 302, "Found");
+ response.setHeader("Location", "data:text/html," + escape(DATA_URI), false);
+}
diff --git a/dom/security/test/general/file_data_download.html b/dom/security/test/general/file_data_download.html
new file mode 100644
index 000000000..4cc92fe8f
--- /dev/null
+++ b/dom/security/test/general/file_data_download.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test download attribute for data: URI</title>
+</head>
+<body>
+ <a href="data:text/html,<body>data download</body>" download="data-foo.html" id="testlink">download data</a>
+ <script>
+ // click the link to have the downoad panel appear
+ let testlink = document.getElementById("testlink");
+ testlink.click();
+ </script>
+ </body>
+</html>
diff --git a/dom/security/test/general/file_data_text_csv.html b/dom/security/test/general/file_data_text_csv.html
new file mode 100644
index 000000000..a9ac369d1
--- /dev/null
+++ b/dom/security/test/general/file_data_text_csv.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test open data:text/csv</title>
+</head>
+<body>
+ <a href="data:text/csv;foo,bar,foobar" id="testlink">test text/csv</a>
+ <script>
+ // click the link to have the downoad panel appear
+ let testlink = document.getElementById("testlink");
+ testlink.click();
+ </script>
+ </body>
+</html>
diff --git a/dom/security/test/general/file_toplevel_data_meta_redirect.html b/dom/security/test/general/file_toplevel_data_meta_redirect.html
new file mode 100644
index 000000000..f4f5deb52
--- /dev/null
+++ b/dom/security/test/general/file_toplevel_data_meta_redirect.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<head>
+ <meta http-equiv="refresh"
+ content="0; url='data:text/html,<body>toplevel meta redirect to data: URI should be blocked</body>'">
+</head>
+<body>
+Meta Redirect to data: URI
+</body>
+</html>
diff --git a/dom/security/test/general/file_toplevel_data_navigations.sjs b/dom/security/test/general/file_toplevel_data_navigations.sjs
new file mode 100644
index 000000000..501b833e5
--- /dev/null
+++ b/dom/security/test/general/file_toplevel_data_navigations.sjs
@@ -0,0 +1,14 @@
+// Custom *.sjs file specifically for the needs of Bug:
+// Bug 1394554 - Block toplevel data: URI navigations after redirect
+
+var DATA_URI =
+ "data:text/html,<body>toplevel data: URI navigations after redirect should be blocked</body>";
+
+function handleRequest(request, response)
+{
+ // avoid confusing cache behaviors
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ response.setStatusLine("1.1", 302, "Found");
+ response.setHeader("Location", DATA_URI, false);
+}
diff --git a/dom/security/test/general/file_view_image_data_navigation.html b/dom/security/test/general/file_view_image_data_navigation.html
new file mode 100644
index 000000000..a3f9acfb4
--- /dev/null
+++ b/dom/security/test/general/file_view_image_data_navigation.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1407891: Test navigation for right-click view-image on data:image/svg</title>
+</head>
+<body>
+
+<img id="testimage" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg=="></img>
+
+</body>
+</html>
diff --git a/dom/security/test/general/mochitest.ini b/dom/security/test/general/mochitest.ini
index 70c0c9fb6..f3bcca072 100644
--- a/dom/security/test/general/mochitest.ini
+++ b/dom/security/test/general/mochitest.ini
@@ -3,7 +3,19 @@ support-files =
file_contentpolicytype_targeted_link_iframe.sjs
file_nosniff_testserver.sjs
file_block_script_wrong_mime_server.sjs
+ file_block_toplevel_data_navigation.html
+ file_block_toplevel_data_navigation2.html
+ file_block_toplevel_data_navigation3.html
+ file_block_toplevel_data_redirect.sjs
[test_contentpolicytype_targeted_link_iframe.html]
[test_nosniff.html]
[test_block_script_wrong_mime.html]
+[test_block_toplevel_data_navigation.html]
+skip-if = toolkit == 'android' # intermittent failure
+[test_block_toplevel_data_img_navigation.html]
+skip-if = toolkit == 'android' # intermittent failure
+[test_allow_opening_data_pdf.html]
+skip-if = toolkit == 'android'
+[test_allow_opening_data_json.html]
+skip-if = toolkit == 'android'
diff --git a/dom/security/test/general/test_allow_opening_data_json.html b/dom/security/test/general/test_allow_opening_data_json.html
new file mode 100644
index 000000000..1530a24e8
--- /dev/null
+++ b/dom/security/test/general/test_allow_opening_data_json.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1403814: Allow toplevel data URI navigation data:application/json</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function test_toplevel_data_json() {
+ const DATA_JSON = "data:application/json,{'my_json_key':'my_json_value'}";
+
+ let win = window.open(DATA_JSON);
+ let wrappedWin = SpecialPowers.wrap(win);
+
+ // Unfortunately we can't detect whether the JSON has loaded or not using some
+ // event, hence we are constantly polling location.href till we see that
+ // the data: URI appears. Test times out on failure.
+ var jsonLoaded = setInterval(function() {
+ if (wrappedWin.document.location.href.startsWith("data:application/json")) {
+ clearInterval(jsonLoaded);
+ ok(true, "navigating to data:application/json allowed");
+ wrappedWin.close();
+ SimpleTest.finish();
+ }
+ }, 200);
+}
+
+SpecialPowers.pushPrefEnv({
+ set: [["security.data_uri.block_toplevel_data_uri_navigations", true]]
+}, test_toplevel_data_json);
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/test_allow_opening_data_pdf.html b/dom/security/test/general/test_allow_opening_data_pdf.html
new file mode 100644
index 000000000..6b51fe57b
--- /dev/null
+++ b/dom/security/test/general/test_allow_opening_data_pdf.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1398692: Allow toplevel navigation to a data:application/pdf</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function test_toplevel_data_pdf() {
+ // The PDF contains one page and it is a 3/72" square, the minimum allowed by the spec
+ const DATA_PDF =
+ "data:application/pdf;base64,JVBERi0xLjANCjEgMCBvYmo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iaiAyIDAgb2JqPDwvVHlwZS9QYWdlcy9LaWRzWzMgMCBSXS9Db3VudCAxPj5lbmRvYmogMyAwIG9iajw8L1R5cGUvUGFnZS9NZWRpYUJveFswIDAgMyAzXT4+ZW5kb2JqDQp4cmVmDQowIDQNCjAwMDAwMDAwMDAgNjU1MzUgZg0KMDAwMDAwMDAxMCAwMDAwMCBuDQowMDAwMDAwMDUzIDAwMDAwIG4NCjAwMDAwMDAxMDIgMDAwMDAgbg0KdHJhaWxlcjw8L1NpemUgNC9Sb290IDEgMCBSPj4NCnN0YXJ0eHJlZg0KMTQ5DQolRU9G";
+
+ let win = window.open(DATA_PDF);
+ let wrappedWin = SpecialPowers.wrap(win);
+
+ // Unfortunately we can't detect whether the PDF has loaded or not using some
+ // event, hence we are constantly polling location.href till we see that
+ // the data: URI appears. Test times out on failure.
+ var pdfLoaded = setInterval(function() {
+ if (wrappedWin.document.location.href.startsWith("data:application/pdf")) {
+ clearInterval(pdfLoaded);
+ ok(true, "navigating to data:application/pdf allowed");
+ wrappedWin.close();
+ SimpleTest.finish();
+ }
+ }, 200);
+}
+
+SpecialPowers.pushPrefEnv({
+ set: [["security.data_uri.block_toplevel_data_uri_navigations", true]]
+}, test_toplevel_data_pdf);
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/test_block_script_wrong_mime.html b/dom/security/test/general/test_block_script_wrong_mime.html
index f4da9c577..34d4b621b 100644
--- a/dom/security/test/general/test_block_script_wrong_mime.html
+++ b/dom/security/test/general/test_block_script_wrong_mime.html
@@ -53,9 +53,6 @@ function testWorker([mime, shouldLoad]) {
};
worker.onerror = (error) => {
ok(!shouldLoad, `worker with wrong mime '${mime}' should be blocked`);
- let msg = error.message;
- ok(msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/),
- "should gets correct error message");
error.preventDefault();
resolve();
}
@@ -74,9 +71,6 @@ function testWorkerImportScripts([mime, shouldLoad]) {
};
worker.onerror = (error) => {
ok(!shouldLoad, `worker/importScripts with wrong mime '${mime}' should be blocked`);
- let msg = error.message;
- ok(msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/),
- "should gets correct error message");
error.preventDefault();
resolve();
}
diff --git a/dom/security/test/general/test_block_toplevel_data_img_navigation.html b/dom/security/test/general/test_block_toplevel_data_img_navigation.html
new file mode 100644
index 000000000..7f8dfc748
--- /dev/null
+++ b/dom/security/test/general/test_block_toplevel_data_img_navigation.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1396798: Do not block toplevel data: navigation to image (except svgs)</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+SpecialPowers.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
+SimpleTest.registerCleanupFunction(() => {
+ SpecialPowers.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
+});
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("have to test that top level data:image loading is blocked/allowed");
+
+function test_toplevel_data_image() {
+ const DATA_PNG =
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
+ let win1 = window.open(DATA_PNG);
+ let wrappedWin1 = SpecialPowers.wrap(win1);
+ setTimeout(function () {
+ let images = wrappedWin1.document.getElementsByTagName('img');
+ is(images.length, 1, "Loading data:image/png should be allowed");
+ is(images[0].src, DATA_PNG, "Sanity: img src matches");
+ wrappedWin1.close();
+ test_toplevel_data_image_svg();
+ }, 1000);
+}
+
+function test_toplevel_data_image_svg() {
+ const DATA_SVG =
+ "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg==";
+ let win2 = window.open(DATA_SVG);
+ // Unfortunately we can't detect whether the window was closed using some event,
+ // hence we are constantly polling till we see that win == null.
+ // Test times out on failure.
+ var win2Closed = setInterval(function() {
+ if (win2 == null || win2.closed) {
+ clearInterval(win2Closed);
+ ok(true, "Loading data:image/svg+xml should be blocked");
+ SimpleTest.finish();
+ }
+ }, 200);
+}
+// fire up the tests
+test_toplevel_data_image();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/test_block_toplevel_data_navigation.html b/dom/security/test/general/test_block_toplevel_data_navigation.html
new file mode 100644
index 000000000..cef232b65
--- /dev/null
+++ b/dom/security/test/general/test_block_toplevel_data_navigation.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1331351 - Block top level window data: URI navigations</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+SpecialPowers.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
+SimpleTest.registerCleanupFunction(() => {
+ SpecialPowers.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
+});
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("have to test that top level data: URI navgiation is blocked");
+
+function test1() {
+ // simple data: URI click navigation should be prevented
+ let TEST_FILE = "file_block_toplevel_data_navigation.html";
+ let win1 = window.open(TEST_FILE);
+ setTimeout(function () {
+ ok(SpecialPowers.wrap(win1).document.body.innerHTML.indexOf("test1:") !== -1,
+ "toplevel data: URI navigation through click() should be blocked");
+ win1.close();
+ test2();
+ }, 1000);
+}
+
+function test2() {
+ // data: URI in iframe which opens data: URI in _blank should be blocked
+ let win2 = window.open("file_block_toplevel_data_navigation2.html");
+ window.addEventListener("message", receiveMessage);
+ function receiveMessage(event) {
+ window.removeEventListener("message", receiveMessage);
+ is(event.data, "blocked",
+ "data: URI navigation using _blank from data: URI should be blocked");
+ win2.close();
+ test3();
+ }
+}
+
+function test3() {
+ // navigating to a data: URI using window.location.href should be blocked
+ let win3 = window.open("file_block_toplevel_data_navigation3.html");
+ setTimeout(function () {
+ ok(win3.document.body.innerHTML.indexOf("test3:") !== -1,
+ "data: URI navigation through win.loc.href should be blocked");
+ win3.close();
+ test4();
+ }, 1000);
+}
+
+function test4() {
+ // navigating to a data: URI using window.open() should be blocked
+ let win4 = window.open("data:text/html,<body>toplevel data: URI navigations should be blocked</body>");
+ setTimeout(function () {
+ // Please note that the data: URI will be displayed in the URL-Bar but not
+ // loaded, hence we rather rely on document.body than document.location
+ is(win4.document.body.innerHTML, "",
+ "navigating to a data: URI using window.open() should be blocked");
+ test5();
+ }, 1000);
+}
+
+function test5() {
+ // navigating to a URI which redirects to a data: URI using window.open() should be blocked
+ let win5 = window.open("file_block_toplevel_data_redirect.sjs");
+ setTimeout(function () {
+ // Please note that the data: URI will be displayed in the URL-Bar but not
+ // loaded, hence we rather rely on document.body than document.location
+ is(SpecialPowers.wrap(win5).document.body.innerHTML, "",
+ "navigating to URI which redirects to a data: URI using window.open() should be blocked");
+ win5.close();
+ SimpleTest.finish();
+ }, 1000);
+}
+
+// fire up the tests
+test1();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html
index 7b1ab72dc..3ef243824 100644
--- a/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html
+++ b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html
@@ -61,6 +61,7 @@ var policy = {
"content policy type should TYPESUBDOCUMENT");
categoryManager.deleteCategoryEntry("content-policy", POLICYNAME, false);
SimpleTest.finish();
+ return Ci.nsIContentPolicy.REJECT_REQUEST;
}
return Ci.nsIContentPolicy.ACCEPT;
},
diff --git a/dom/security/test/gtest/TestCSPParser.cpp b/dom/security/test/gtest/TestCSPParser.cpp
index fafa7b5d9..893e02db5 100644
--- a/dom/security/test/gtest/TestCSPParser.cpp
+++ b/dom/security/test/gtest/TestCSPParser.cpp
@@ -204,6 +204,8 @@ TEST(CSPParser, Directives)
{
static const PolicyTest policies[] =
{
+ { "connect-src xn--mnchen-3ya.de",
+ "connect-src http://xn--mnchen-3ya.de"},
{ "default-src http://www.example.com",
"default-src http://www.example.com" },
{ "script-src http://www.example.com",
@@ -238,6 +240,10 @@ TEST(CSPParser, Directives)
"script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https:" },
{ "default-src 'sha256-siVR8' 'strict-dynamic' 'unsafe-inline' https: ",
"default-src 'sha256-siVR8' 'unsafe-inline' https:" },
+ { "worker-src https://example.com",
+ "worker-src https://example.com" },
+ { "worker-src http://worker.com; frame-src http://frame.com; child-src http://child.com",
+ "worker-src http://worker.com; frame-src http://frame.com; child-src http://child.com" },
};
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
diff --git a/dom/security/test/moz.build b/dom/security/test/moz.build
index ddb4e9b89..946959dee 100644
--- a/dom/security/test/moz.build
+++ b/dom/security/test/moz.build
@@ -27,5 +27,6 @@ MOCHITEST_CHROME_MANIFESTS += [
BROWSER_CHROME_MANIFESTS += [
'contentverifier/browser.ini',
'csp/browser.ini',
+ 'general/browser.ini',
'hsts/browser.ini',
]