<!DOCTYPE HTML> <html> <!-- Tests for Mixed Content Blocker https://bugzilla.mozilla.org/show_bug.cgi?id=62178 --> <head> <meta charset="utf-8"> <title>Tests for Bug 62178</title> <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> </head> <body> <div id="testContent"></div> <!-- types the Mixed Content Blocker can block /* switch (aContentType) { case nsIContentPolicy::TYPE_OBJECT: case nsIContentPolicy::TYPE_SCRIPT: case nsIContentPolicy::TYPE_STYLESHEET: case nsIContentPolicy::TYPE_SUBDOCUMENT: case nsIContentPolicy::TYPE_XMLHTTPREQUEST: case nsIContentPolicy::TYPE_FONT: - NO TEST: Load events for external fonts are not detectable by javascript. case nsIContentPolicy::TYPE_WEBSOCKET: - NO TEST: websocket connections over https require an encrypted websocket protocol (wss:) case nsIContentPolicy::TYPE_IMAGE: case nsIContentPolicy::TYPE_IMAGESET: case nsIContentPolicy::TYPE_MEDIA: case nsIContentPolicy::TYPE_PING: our ping implementation is off by default and does not comply with the current spec (bug 786347) case nsIContentPolicy::TYPE_BEACON: } */ --> <script> var baseUrl = "http://example.com/tests/dom/security/test/mixedcontentblocker/file_server.sjs"; //For tests that require setTimeout, set the maximum polling time to 100 x 100ms = 10 seconds. var MAX_COUNT = 100; var TIMEOUT_INTERVAL = 100; var testContent = document.getElementById("testContent"); /* Part 1: Mixed Script tests */ // Test 1a: insecure object var object = document.createElement("object"); object.data = baseUrl + "?type=object"; object.type = "application/x-test"; object.width = "200"; object.height = "200"; testContent.appendChild(object); var objectCount = 0; function objectStatus(object) { // Expose our privileged bits on the object object = SpecialPowers.wrap(object); if (object.displayedType != SpecialPowers.Ci.nsIObjectLoadingContent.TYPE_NULL) { //object loaded parent.postMessage({"test": "object", "msg": "insecure object loaded"}, "http://mochi.test:8888"); } else { if(objectCount < MAX_COUNT) { objectCount++; setTimeout(objectStatus, TIMEOUT_INTERVAL, object); } else { //After we have called setTimeout the maximum number of times, assume object is blocked parent.postMessage({"test": "object", "msg": "insecure object blocked"}, "http://mochi.test:8888"); } } } // object does not have onload and onerror events. Hence we need a setTimeout to check the object's status setTimeout(objectStatus, TIMEOUT_INTERVAL, object); // Test 1b: insecure script var script = document.createElement("script"); var scriptLoad = false; var scriptCount = 0; script.src = baseUrl + "?type=script"; script.onload = function() { parent.postMessage({"test": "script", "msg": "insecure script loaded"}, "http://mochi.test:8888"); scriptLoad = true; } testContent.appendChild(script); function scriptStatus(script) { if(scriptLoad) { return; } else { if(scriptCount < MAX_COUNT) { scriptCount++; setTimeout(scriptStatus, TIMEOUT_INTERVAL, script); } else { //After we have called setTimeout the maximum number of times, assume script is blocked parent.postMessage({"test": "script", "msg": "insecure script blocked"}, "http://mochi.test:8888"); } } } // scripts blocked by Content Policy's do not have onerror events (see bug 789856). Hence we need a setTimeout to check the script's status setTimeout(scriptStatus, TIMEOUT_INTERVAL, script); // Test 1c: insecure stylesheet var cssStyleSheet = document.createElement("link"); cssStyleSheet.rel = "stylesheet"; cssStyleSheet.href = baseUrl + "?type=stylesheet"; cssStyleSheet.type = "text/css"; testContent.appendChild(cssStyleSheet); var styleCount = 0; function styleStatus(cssStyleSheet) { if( cssStyleSheet.sheet || cssStyleSheet.styleSheet || cssStyleSheet.innerHTML ) { parent.postMessage({"test": "stylesheet", "msg": "insecure stylesheet loaded"}, "http://mochi.test:8888"); } else { if(styleCount < MAX_COUNT) { styleCount++; setTimeout(styleStatus, TIMEOUT_INTERVAL, cssStyleSheet); } else { //After we have called setTimeout the maximum number of times, assume stylesheet is blocked parent.postMessage({"test": "stylesheet", "msg": "insecure stylesheet blocked"}, "http://mochi.test:8888"); } } } // link does not have onload and onerror events. Hence we need a setTimeout to check the link's status window.setTimeout(styleStatus, TIMEOUT_INTERVAL, cssStyleSheet); // Test 1d: insecure iframe var iframe = document.createElement("iframe"); iframe.src = baseUrl + "?type=iframe"; iframe.onload = function() { parent.postMessage({"test": "iframe", "msg": "insecure iframe loaded"}, "http://mochi.test:8888"); } iframe.onerror = function() { parent.postMessage({"test": "iframe", "msg": "insecure iframe blocked"}, "http://mochi.test:8888"); }; testContent.appendChild(iframe); // Test 1e: insecure xhr var xhr = new XMLHttpRequest; try { xhr.open("GET", baseUrl + "?type=xhr", true); xhr.send(); xhr.onloadend = function (oEvent) { if (xhr.status == 200) { parent.postMessage({"test": "xhr", "msg": "insecure xhr loaded"}, "http://mochi.test:8888"); } else { parent.postMessage({"test": "xhr", "msg": "insecure xhr blocked"}, "http://mochi.test:8888"); } } } catch(ex) { parent.postMessage({"test": "xhr", "msg": "insecure xhr blocked"}, "http://mochi.test:8888"); } /* Part 2: Mixed Display tests */ // Shorthand for all image test variants function imgHandlers(img, test) { img.onload = function () { parent.postMessage({"test": test, "msg": "insecure image loaded"}, "http://mochi.test:8888"); } img.onerror = function() { parent.postMessage({"test": test, "msg": "insecure image blocked"}, "http://mochi.test:8888"); } } // Test 2a: insecure image var img = document.createElement("img"); img.src = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; imgHandlers(img, "image"); // We don't need to append the image to the document. Doing so causes the image test to run twice. // Test 2b: insecure media var media = document.createElement("video"); media.src = "http://mochi.test:8888/tests/dom/media/test/320x240.ogv?" + Math.floor((Math.random()*1000)+1); media.width = "320"; media.height = "200"; media.type = "video/ogg"; media.onloadeddata = function() { parent.postMessage({"test": "media", "msg": "insecure media loaded"}, "http://mochi.test:8888"); } media.onerror = function() { parent.postMessage({"test": "media", "msg": "insecure media blocked"}, "http://mochi.test:8888"); } // We don't need to append the video to the document. Doing so causes the image test to run twice. /* Part 3: Mixed Active Tests for Image srcset */ // Test 3a: image with srcset var imgA = document.createElement("img"); imgA.srcset = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; imgHandlers(imgA, "imageSrcset"); // Test 3b: image with srcset, using fallback from src, should still use imageset policy var imgB = document.createElement("img"); imgB.srcset = " "; imgB.src = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; imgHandlers(imgB, "imageSrcsetFallback"); // Test 3c: image in <picture> var imgC = document.createElement("img"); var pictureC = document.createElement("picture"); var sourceC = document.createElement("source"); sourceC.srcset = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; pictureC.appendChild(sourceC); pictureC.appendChild(imgC); imgHandlers(imgC, "imagePicture"); // Test 3d: Loaded basic image switching to a <picture>, loading // same source, should still redo the request with new // policy. var imgD = document.createElement("img"); imgD.src = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; imgD.onload = imgD.onerror = function() { // Whether or not it loads, we want to now append it to a picture and observe var pictureD = document.createElement("picture"); var sourceD = document.createElement("source"); sourceD.srcset = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; pictureD.appendChild(sourceD); pictureD.appendChild(imgD); imgHandlers(imgD, "imageJoinPicture"); } // Test 3e: img load from <picture> source reverts to img.src as it // is removed -- the new request should revert to mixed // display policy var imgE = document.createElement("img"); var pictureE = document.createElement("picture"); var sourceE = document.createElement("source"); sourceE.srcset = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; pictureE.appendChild(sourceE); pictureE.appendChild(imgE); imgE.src = "http://mochi.test:8888/tests/image/test/mochitest/blue.png"; imgE.onload = imgE.onerror = function() { // Whether or not it loads, remove it from the picture and observe pictureE.removeChild(imgE) imgHandlers(imgE, "imageLeavePicture"); } </script> </body> </html>