Skip to content

Commit

Permalink
Bug 1272239 - P3. Testcase, test gethash. r=francois
Browse files Browse the repository at this point in the history
--HG--
extra : rebase_source : df9a20cc3ca80df5bf630a4ccb3a16adc4511ac5
  • Loading branch information
DimiDL committed Jun 14, 2016
1 parent 1ba65bb commit 987ad86
Show file tree
Hide file tree
Showing 8 changed files with 382 additions and 4 deletions.
1 change: 1 addition & 0 deletions toolkit/components/url-classifier/tests/mochitest/bad.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#styleBad { visibility: hidden; }
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
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) {
Expand All @@ -36,13 +44,14 @@
<!-- 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>

<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>
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
Expand All @@ -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) {
Expand All @@ -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 +=
Expand All @@ -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" +
Expand Down Expand Up @@ -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();
}
Expand Down
119 changes: 119 additions & 0 deletions toolkit/components/url-classifier/tests/mochitest/gethash.sjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<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>
6 changes: 3 additions & 3 deletions toolkit/components/url-classifier/tests/mochitest/import.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* malware.example.com is in the malware database.
classifierBad.css does not actually exist. */
@import url("http://malware.example.com/tests/docshell/test/classifierBad.css");
/* malware.example.com is in the malware database. */
@import url("http://malware.example.com/tests/toolkit/components/url-classifier/tests/mochitest/bad.css");
#styleImport { visibility: hidden; }
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ support-files =
classifierHelper.js
cleanWorker.js
good.js
bad.css
evil.css
evil.js
evil.js^headers^
Expand All @@ -22,6 +23,8 @@ support-files =
basic.vtt
dnt.html
dnt.sjs
gethash.sjs
gethashFrame.html

[test_classifier.html]
skip-if = (os == 'linux' && debug) #Bug 1199778
Expand Down
Loading

0 comments on commit 987ad86

Please sign in to comment.