Loading toolkit/components/url-classifier/tests/mochitest/bad.css 0 → 100644 +1 −0 Original line number Diff line number Diff line #styleBad { visibility: hidden; } toolkit/components/url-classifier/tests/mochitest/classifierFrame.html +10 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,14 @@ function checkLoads() { var style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); elt = document.getElementById("styleBad"); style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); elt = document.getElementById("styleImport"); style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "visible", "Should import clean css"); // Call parent.loadTestFrame again to test classification metadata in HTTP // cache entries. if (window.parent.firstLoad) { Loading @@ -36,7 +44,6 @@ function checkLoads() { <!-- Try loading from an uwanted software css URI --> <link rel="stylesheet" type="text/css" href="http://unwanted.example.com/tests/toolkit/components/url-classifier/tests/mochitest/evil.css"></link> <!-- XXX How is this part of the test supposed to work (= be checked)? --> <!-- Try loading a marked-as-malware css through an @import from a clean URI --> <link rel="stylesheet" type="text/css" href="import.css"></link> </head> Loading @@ -44,5 +51,7 @@ function checkLoads() { <body onload="checkLoads()"> The following should not be hidden: <div id="styleCheck">STYLE TEST</div> <div id="styleBad">STYLE BAD</div> <div id="styleImport">STYLE IMPORT</div> </body> </html> toolkit/components/url-classifier/tests/mochitest/classifierHelper.js +34 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,12 @@ const ADD_CHUNKNUM = 524; const SUB_CHUNKNUM = 523; const HASHLEN = 32; const PREFS = { PROVIDER_LISTS : "browser.safebrowsing.provider.mozilla.lists", DISALLOW_COMPLETIONS : "urlclassifier.disallow_completions", PROVIDER_GETHASHURL : "browser.safebrowsing.provider.mozilla.gethashURL" }; // addUrlToDB & removeUrlFromDB are asynchronous, queue the task to ensure // the callback follow correct order. classifierHelper._updates = []; Loading @@ -17,6 +23,27 @@ classifierHelper._updates = []; // removed after test complete. classifierHelper._updatesToCleanup = []; // This function is used to allow completion for specific "list", // some lists like "test-malware-simple" is default disabled to ask for complete. // "list" is the db we would like to allow it // "url" is the completion server classifierHelper.allowCompletion = function(lists, url) { for (var list of lists) { // Add test db to provider var pref = SpecialPowers.getCharPref(PREFS.PROVIDER_LISTS); pref += "," + list; SpecialPowers.setCharPref(PREFS.PROVIDER_LISTS, pref); // Rename test db so we will not disallow it from completions pref = SpecialPowers.getCharPref(PREFS.DISALLOW_COMPLETIONS); pref = pref.replace(list, list + "-backup"); SpecialPowers.setCharPref(PREFS.DISALLOW_COMPLETIONS, pref); } // Set get hash url SpecialPowers.setCharPref(PREFS.PROVIDER_GETHASHURL, url); } // Pass { url: ..., db: ... } to add url to database, // onsuccess/onerror will be called when update complete. classifierHelper.addUrlToDB = function(updateData) { Loading @@ -26,6 +53,7 @@ classifierHelper.addUrlToDB = function(updateData) { var LISTNAME = update.db; var CHUNKDATA = update.url; var CHUNKLEN = CHUNKDATA.length; var HASHLEN = update.len ? update.len : 32; classifierHelper._updatesToCleanup.push(update); testUpdate += Loading @@ -49,6 +77,7 @@ classifierHelper.removeUrlFromDB = function(updateData) { var LISTNAME = update.db; var CHUNKDATA = ADD_CHUNKNUM + ":" + update.url; var CHUNKLEN = CHUNKDATA.length; var HASHLEN = update.len ? update.len : 32; testUpdate += "n:1000\n" + Loading Loading @@ -127,6 +156,11 @@ classifierHelper._setup = function() { }; classifierHelper._cleanup = function() { // clean all the preferences may touch by helper for (var pref in PREFS) { SpecialPowers.clearUserPref(pref); } if (!classifierHelper._updatesToCleanup) { return Promise.resolve(); } Loading toolkit/components/url-classifier/tests/mochitest/gethash.sjs 0 → 100644 +119 −0 Original line number Diff line number Diff line const CC = Components.Constructor; const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", "setInputStream"); function handleRequest(request, response) { var query = {}; request.queryString.split('&').forEach(function (val) { var idx = val.indexOf('='); query[val.slice(0, idx)] = unescape(val.slice(idx + 1)); }); // Store fullhash in the server side. if ("list" in query && "fullhash" in query) { // In the server side we will store: // 1. All the full hashes for a given list // 2. All the lists we have right now // data is separate by '\n' let list = query["list"]; let hashes = getState(list); let hash = base64ToString(query["fullhash"]); hashes += hash + "\n"; setState(list, hashes); let lists = getState("lists"); if (lists.indexOf(list) == -1) { lists += list + "\n"; setState("lists", lists); } return; } var body = new BinaryInputStream(request.bodyInputStream); var avail; var bytes = []; while ((avail = body.available()) > 0) { Array.prototype.push.apply(bytes, body.readByteArray(avail)); } var responseBody = parseV2Request(bytes); response.setHeader("Content-Type", "text/plain", false); response.write(responseBody); } function parseV2Request(bytes) { var request = String.fromCharCode.apply(this, bytes); var [HEADER, PREFIXES] = request.split("\n"); var [PREFIXSIZE, LENGTH] = HEADER.split(":").map(val => { return parseInt(val); }); var ret = ""; for(var start = 0; start < LENGTH; start += PREFIXSIZE) { getState("lists").split("\n").forEach(function(list) { var completions = getState(list).split("\n"); for (var completion of completions) { if (completion.indexOf(PREFIXES.substr(start, PREFIXSIZE)) == 0) { ret += list + ":" + "1" + ":" + "32" + "\n"; ret += completion; } } }); } return ret; } /* Convert Base64 data to a string */ const toBinaryTable = [ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 ]; const base64Pad = '='; function base64ToString(data) { var result = ''; var leftbits = 0; // number of bits decoded, but yet to be appended var leftdata = 0; // bits decoded, but yet to be appended // Convert one by one. for (var i = 0; i < data.length; i++) { var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; var padding = (data[i] == base64Pad); // Skip illegal characters and whitespace if (c == -1) continue; // Collect data into leftdata, update bitcount leftdata = (leftdata << 6) | c; leftbits += 6; // If we have 8 or more bits, append 8 bits to the result if (leftbits >= 8) { leftbits -= 8; // Append if not padding. if (!padding) result += String.fromCharCode((leftdata >> leftbits) & 0xff); leftdata &= (1 << leftbits) - 1; } } // If there are any bits left, the base64 string was corrupted if (leftbits) throw Components.Exception('Corrupted base64 string'); return result; } toolkit/components/url-classifier/tests/mochitest/gethashFrame.html 0 → 100644 +62 −0 Original line number Diff line number Diff line <html> <head> <title></title> <script type="text/javascript"> var scriptItem = "untouched"; function checkLoads() { var title = document.getElementById("title"); title.innerHTML = window.parent.shouldLoad ? "The following should be hidden:" : "The following should not be hidden:" if (window.parent.shouldLoad) { window.parent.is(scriptItem, "loaded malware javascript!", "Should load bad javascript"); } else { window.parent.is(scriptItem, "untouched", "Should not load bad javascript"); } var elt = document.getElementById("styleImport"); var style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "visible", "Should load clean css"); // Make sure the css did not load. elt = document.getElementById("styleCheck"); style = document.defaultView.getComputedStyle(elt, ""); if (window.parent.shouldLoad) { window.parent.isnot(style.visibility, "visible", "Should load bad css"); } else { window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); } elt = document.getElementById("styleBad"); style = document.defaultView.getComputedStyle(elt, ""); if (window.parent.shouldLoad) { window.parent.isnot(style.visibility, "visible", "Should import bad css"); } else { window.parent.isnot(style.visibility, "hidden", "Should not import bad css"); } } </script> <!-- Try loading from a malware javascript URI --> <script type="text/javascript" src="http://malware.example.com/tests/toolkit/components/url-classifier/tests/mochitest/evil.js"></script> <!-- Try loading from an uwanted software css URI --> <link rel="stylesheet" type="text/css" href="http://unwanted.example.com/tests/toolkit/components/url-classifier/tests/mochitest/evil.css"></link> <!-- Try loading a marked-as-malware css through an @import from a clean URI --> <link rel="stylesheet" type="text/css" href="import.css"></link> </head> <body onload="checkLoads()"> <div id="title"></div> <div id="styleCheck">STYLE EVIL</div> <div id="styleBad">STYLE BAD</div> <div id="styleImport">STYLE IMPORT</div> </body> </html> Loading
toolkit/components/url-classifier/tests/mochitest/bad.css 0 → 100644 +1 −0 Original line number Diff line number Diff line #styleBad { visibility: hidden; }
toolkit/components/url-classifier/tests/mochitest/classifierFrame.html +10 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,14 @@ function checkLoads() { var style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); elt = document.getElementById("styleBad"); style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); elt = document.getElementById("styleImport"); style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "visible", "Should import clean css"); // Call parent.loadTestFrame again to test classification metadata in HTTP // cache entries. if (window.parent.firstLoad) { Loading @@ -36,7 +44,6 @@ function checkLoads() { <!-- Try loading from an uwanted software css URI --> <link rel="stylesheet" type="text/css" href="http://unwanted.example.com/tests/toolkit/components/url-classifier/tests/mochitest/evil.css"></link> <!-- XXX How is this part of the test supposed to work (= be checked)? --> <!-- Try loading a marked-as-malware css through an @import from a clean URI --> <link rel="stylesheet" type="text/css" href="import.css"></link> </head> Loading @@ -44,5 +51,7 @@ function checkLoads() { <body onload="checkLoads()"> The following should not be hidden: <div id="styleCheck">STYLE TEST</div> <div id="styleBad">STYLE BAD</div> <div id="styleImport">STYLE IMPORT</div> </body> </html>
toolkit/components/url-classifier/tests/mochitest/classifierHelper.js +34 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,12 @@ const ADD_CHUNKNUM = 524; const SUB_CHUNKNUM = 523; const HASHLEN = 32; const PREFS = { PROVIDER_LISTS : "browser.safebrowsing.provider.mozilla.lists", DISALLOW_COMPLETIONS : "urlclassifier.disallow_completions", PROVIDER_GETHASHURL : "browser.safebrowsing.provider.mozilla.gethashURL" }; // addUrlToDB & removeUrlFromDB are asynchronous, queue the task to ensure // the callback follow correct order. classifierHelper._updates = []; Loading @@ -17,6 +23,27 @@ classifierHelper._updates = []; // removed after test complete. classifierHelper._updatesToCleanup = []; // This function is used to allow completion for specific "list", // some lists like "test-malware-simple" is default disabled to ask for complete. // "list" is the db we would like to allow it // "url" is the completion server classifierHelper.allowCompletion = function(lists, url) { for (var list of lists) { // Add test db to provider var pref = SpecialPowers.getCharPref(PREFS.PROVIDER_LISTS); pref += "," + list; SpecialPowers.setCharPref(PREFS.PROVIDER_LISTS, pref); // Rename test db so we will not disallow it from completions pref = SpecialPowers.getCharPref(PREFS.DISALLOW_COMPLETIONS); pref = pref.replace(list, list + "-backup"); SpecialPowers.setCharPref(PREFS.DISALLOW_COMPLETIONS, pref); } // Set get hash url SpecialPowers.setCharPref(PREFS.PROVIDER_GETHASHURL, url); } // Pass { url: ..., db: ... } to add url to database, // onsuccess/onerror will be called when update complete. classifierHelper.addUrlToDB = function(updateData) { Loading @@ -26,6 +53,7 @@ classifierHelper.addUrlToDB = function(updateData) { var LISTNAME = update.db; var CHUNKDATA = update.url; var CHUNKLEN = CHUNKDATA.length; var HASHLEN = update.len ? update.len : 32; classifierHelper._updatesToCleanup.push(update); testUpdate += Loading @@ -49,6 +77,7 @@ classifierHelper.removeUrlFromDB = function(updateData) { var LISTNAME = update.db; var CHUNKDATA = ADD_CHUNKNUM + ":" + update.url; var CHUNKLEN = CHUNKDATA.length; var HASHLEN = update.len ? update.len : 32; testUpdate += "n:1000\n" + Loading Loading @@ -127,6 +156,11 @@ classifierHelper._setup = function() { }; classifierHelper._cleanup = function() { // clean all the preferences may touch by helper for (var pref in PREFS) { SpecialPowers.clearUserPref(pref); } if (!classifierHelper._updatesToCleanup) { return Promise.resolve(); } Loading
toolkit/components/url-classifier/tests/mochitest/gethash.sjs 0 → 100644 +119 −0 Original line number Diff line number Diff line const CC = Components.Constructor; const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", "setInputStream"); function handleRequest(request, response) { var query = {}; request.queryString.split('&').forEach(function (val) { var idx = val.indexOf('='); query[val.slice(0, idx)] = unescape(val.slice(idx + 1)); }); // Store fullhash in the server side. if ("list" in query && "fullhash" in query) { // In the server side we will store: // 1. All the full hashes for a given list // 2. All the lists we have right now // data is separate by '\n' let list = query["list"]; let hashes = getState(list); let hash = base64ToString(query["fullhash"]); hashes += hash + "\n"; setState(list, hashes); let lists = getState("lists"); if (lists.indexOf(list) == -1) { lists += list + "\n"; setState("lists", lists); } return; } var body = new BinaryInputStream(request.bodyInputStream); var avail; var bytes = []; while ((avail = body.available()) > 0) { Array.prototype.push.apply(bytes, body.readByteArray(avail)); } var responseBody = parseV2Request(bytes); response.setHeader("Content-Type", "text/plain", false); response.write(responseBody); } function parseV2Request(bytes) { var request = String.fromCharCode.apply(this, bytes); var [HEADER, PREFIXES] = request.split("\n"); var [PREFIXSIZE, LENGTH] = HEADER.split(":").map(val => { return parseInt(val); }); var ret = ""; for(var start = 0; start < LENGTH; start += PREFIXSIZE) { getState("lists").split("\n").forEach(function(list) { var completions = getState(list).split("\n"); for (var completion of completions) { if (completion.indexOf(PREFIXES.substr(start, PREFIXSIZE)) == 0) { ret += list + ":" + "1" + ":" + "32" + "\n"; ret += completion; } } }); } return ret; } /* Convert Base64 data to a string */ const toBinaryTable = [ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 ]; const base64Pad = '='; function base64ToString(data) { var result = ''; var leftbits = 0; // number of bits decoded, but yet to be appended var leftdata = 0; // bits decoded, but yet to be appended // Convert one by one. for (var i = 0; i < data.length; i++) { var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; var padding = (data[i] == base64Pad); // Skip illegal characters and whitespace if (c == -1) continue; // Collect data into leftdata, update bitcount leftdata = (leftdata << 6) | c; leftbits += 6; // If we have 8 or more bits, append 8 bits to the result if (leftbits >= 8) { leftbits -= 8; // Append if not padding. if (!padding) result += String.fromCharCode((leftdata >> leftbits) & 0xff); leftdata &= (1 << leftbits) - 1; } } // If there are any bits left, the base64 string was corrupted if (leftbits) throw Components.Exception('Corrupted base64 string'); return result; }
toolkit/components/url-classifier/tests/mochitest/gethashFrame.html 0 → 100644 +62 −0 Original line number Diff line number Diff line <html> <head> <title></title> <script type="text/javascript"> var scriptItem = "untouched"; function checkLoads() { var title = document.getElementById("title"); title.innerHTML = window.parent.shouldLoad ? "The following should be hidden:" : "The following should not be hidden:" if (window.parent.shouldLoad) { window.parent.is(scriptItem, "loaded malware javascript!", "Should load bad javascript"); } else { window.parent.is(scriptItem, "untouched", "Should not load bad javascript"); } var elt = document.getElementById("styleImport"); var style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "visible", "Should load clean css"); // Make sure the css did not load. elt = document.getElementById("styleCheck"); style = document.defaultView.getComputedStyle(elt, ""); if (window.parent.shouldLoad) { window.parent.isnot(style.visibility, "visible", "Should load bad css"); } else { window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); } elt = document.getElementById("styleBad"); style = document.defaultView.getComputedStyle(elt, ""); if (window.parent.shouldLoad) { window.parent.isnot(style.visibility, "visible", "Should import bad css"); } else { window.parent.isnot(style.visibility, "hidden", "Should not import bad css"); } } </script> <!-- Try loading from a malware javascript URI --> <script type="text/javascript" src="http://malware.example.com/tests/toolkit/components/url-classifier/tests/mochitest/evil.js"></script> <!-- Try loading from an uwanted software css URI --> <link rel="stylesheet" type="text/css" href="http://unwanted.example.com/tests/toolkit/components/url-classifier/tests/mochitest/evil.css"></link> <!-- Try loading a marked-as-malware css through an @import from a clean URI --> <link rel="stylesheet" type="text/css" href="import.css"></link> </head> <body onload="checkLoads()"> <div id="title"></div> <div id="styleCheck">STYLE EVIL</div> <div id="styleBad">STYLE BAD</div> <div id="styleImport">STYLE IMPORT</div> </body> </html>