1
0
mirror of https://github.com/kkapsner/CanvasBlocker synced 2024-12-22 04:40:20 +01:00

Linting of .tools and test

This commit is contained in:
kkapsner 2019-11-30 02:05:37 +01:00
parent aef6bd3d59
commit 17349dcb05
19 changed files with 333 additions and 173 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
!/.tools

View File

@ -6,12 +6,17 @@
"webextensions": true "webextensions": true
}, },
"parserOptions": { "parserOptions": {
"ecmaVersion": 8,
"ecmaFeatures": { "ecmaFeatures": {
"jsx": true "jsx": true
}, },
"sourceType": "script" "sourceType": "script"
}, },
"plugins": ["promise", "eslint-comments"], "plugins": [
"promise",
"eslint-comments",
"html"
],
"extends": [ "extends": [
"eslint:recommended", "eslint:recommended",
"plugin:promise/recommended", "plugin:promise/recommended",
@ -59,9 +64,26 @@
} }
}, },
{ {
"files": ["test/*.js"], "files": ["test/*"],
"rules": { "rules": {
"no-var": "off" "no-var": "off",
"no-console": "off"
}
},
{
"files": [".tools/*.js"],
"env": {
"node": true
},
"rules": {
"no-console": "off"
}
},
{
"files": ["*.html", "*.php"],
"rules": {
"no-useless-escape": "off",
"no-undef": "off"
} }
} }
] ]

View File

@ -7,6 +7,8 @@ const la = require("../_locales/" + language + "/messages.json");
const laKeys = Object.keys(la); const laKeys = Object.keys(la);
enKeys.forEach(function(key){ enKeys.forEach(function(key){
"use strict";
if (en[key].message){ if (en[key].message){
if (!la[key] || !la[key].message){ if (!la[key] || !la[key].message){
console.log(key, "missing"); console.log(key, "missing");

View File

@ -5,6 +5,8 @@ const util = require("util");
function getMessagesInContent(content){ function getMessagesInContent(content){
"use strict";
const foundMessages = []; const foundMessages = [];
[ [
/\b(?:_|browser.i18n.getMessage|extension.getTranslation|notify|extension)\(["']([^"']+)["']\s*(?:\)|,)/g, /\b(?:_|browser.i18n.getMessage|extension.getTranslation|notify|extension)\(["']([^"']+)["']\s*(?:\)|,)/g,
@ -19,58 +21,58 @@ function getMessagesInContent(content){
} }
async function getMessagesInFile(path){ async function getMessagesInFile(path){
return await util.promisify(fs.exists)(path) "use strict";
.then(function(exists){
if (exists){ const exists = await util.promisify(fs.exists)(path);
return util.promisify(fs.readFile)(path, {encoding: "UTF-8"}) if (exists){
.then(function(content){ const content = await util.promisify(fs.readFile)(path, {encoding: "UTF-8"});
return getMessagesInContent(content); return getMessagesInContent(content);
}); }
} else {
else { // eslint-disable-next-line no-console
console.log("file does not exist:", path); console.log("file does not exist:", path);
return []; return [];
} }
});
} }
async function getMessagesInFolder(folder){ async function getMessagesInFolder(folder){
return await util.promisify(fs.readdir)(folder, {encoding: "UTF-8"}) "use strict";
.then(function(files){
return Promise.all( const files = await util.promisify(fs.readdir)(folder, {encoding: "UTF-8"});
files.filter(function(file){
return !file.startsWith("."); const messages = await Promise.all(
}).map(function(file){ files.filter(function(file){
return path.join(folder, file); return !file.startsWith(".");
}).map(function(path){ }).map(function(file){
return util.promisify(fs.stat)(path).then(function(stat){ return path.join(folder, file);
if (stat.isDirectory()){ }).map(async function(path){
return getMessagesInFolder(path); const stat = await util.promisify(fs.stat)(path);
} if (stat.isDirectory()){
else { return getMessagesInFolder(path);
if (path.endsWith(".js")){ }
return getMessagesInFile(path); else {
} if (path.endsWith(".js")){
else { return getMessagesInFile(path);
return []; }
} else {
} return [];
}); }
}) }
).then(function(messages){ })
const flat = []; );
messages.forEach(function(messages){ const flat = [];
messages.forEach(function(message){ messages.forEach(function(messages){
flat.push(message); messages.forEach(function(message){
}); flat.push(message);
});
return flat;
}); });
}) });
return flat;
} }
async function getSettingMessages(){ async function getSettingMessages(){
"use strict";
const settingStrings = require("../lib/settingStrings"); const settingStrings = require("../lib/settingStrings");
const settingDefinitions = require("../lib/settingDefinitions"); const settingDefinitions = require("../lib/settingDefinitions");
function getDefinition(name){ function getDefinition(name){
@ -113,33 +115,53 @@ async function getSettingMessages(){
}); });
}); });
}); });
const presets = require("../options/presets.json");
Object.keys(presets).forEach(function(preset){
foundMessages.push("preset_" + preset + "_title");
foundMessages.push("preset_" + preset + "_description");
});
return foundMessages.map(function(message){return message.toLowerCase();}); return foundMessages.map(function(message){return message.toLowerCase();});
} }
async function getKnownMessages(){ async function getKnownMessages(){
"use strict";
return [ return [
"addon_title", "addon_title",
"addon_description", "addon_description",
"urlsettings_title", "urlSettings_title",
"installnotice", "installnotice",
"presets_installnotice",
"updatenotice", "updatenotice",
"disablenotifications", "disableNotifications",
"showoptions", "showoptions",
"displayhiddensettings_title", "displayHiddenSettings_title",
"displayhiddensettings_description", "displayHiddenSettings_description",
"browseraction_settings", "browseraction_settings",
"browseraction_test", "browseraction_test",
"browseraction_review", "browseraction_review",
"browseraction_reportissue", "browseraction_reportIssue",
]; ].map(function(message){
return message.toLowerCase();
});
} }
const en = require("../_locales/en/messages.json"); async function main(){
const declaredMessages = Object.keys(en) "use strict";
// .filter(function(key){return en[key].message;}) const en = require("../_locales/en/messages.json");
.map(function(key){return key.toLowerCase();}); const declaredMessages = Object.keys(en)
Promise.all([getSettingMessages(), getMessagesInFolder(path.join(__dirname, "..")), getKnownMessages()]).then(function([settingMessages, fileMessages, knownMessages]){ // .filter(function(key){return en[key].message;})
.map(function(key){
return key.toLowerCase();
});
const [settingMessages, fileMessages, knownMessages] = await Promise.all([
getSettingMessages(),
getMessagesInFolder(path.join(__dirname, "..")),
getKnownMessages()]
);
declaredMessages.forEach(function(message){ declaredMessages.forEach(function(message){
if ( if (
fileMessages.indexOf(message) === -1 && fileMessages.indexOf(message) === -1 &&
settingMessages.indexOf(message) === -1 && settingMessages.indexOf(message) === -1 &&
@ -148,4 +170,6 @@ Promise.all([getSettingMessages(), getMessagesInFolder(path.join(__dirname, ".."
console.log(`usage of ${message} not found`); console.log(`usage of ${message} not found`);
} }
}); });
}); }
main();

View File

@ -8,35 +8,39 @@ const language = process.argv[2];
function getTranslationPath(language){ function getTranslationPath(language){
"use strict";
return path.join(__dirname, "../_locales/" + language + "/messages.json"); return path.join(__dirname, "../_locales/" + language + "/messages.json");
} }
async function loadTranslation(language){ async function loadTranslation(language){
"use strict";
const path = getTranslationPath(language); const path = getTranslationPath(language);
return await util.promisify(fs.exists)(path) const exists = await util.promisify(fs.exists)(path);
.then(function(exists){ if (exists){
if (exists){ console.log("language exists -> load data");
console.log("language exists -> load data"); const data = await util.promisify(fs.readFile)(path, {encoding: "UTF-8"});
return util.promisify(fs.readFile)(path, {encoding: "UTF-8"}) return JSON.parse(data);
.then(function(data){ }
return JSON.parse(data); else {
}); console.log("language does not exist -> create it");
} return {};
else { }
console.log("language does not exist -> create it");
return {};
}
});
} }
async function saveTranslation(language, data){ async function saveTranslation(language, data){
"use strict";
const path = getTranslationPath(language); const path = getTranslationPath(language);
return await util.promisify(fs.writeFile)(path, JSON.stringify(data, null, "\t")); return await util.promisify(fs.writeFile)(path, JSON.stringify(data, null, "\t"));
} }
async function getInput(prompt){ async function getInput(prompt){
return new Promise(function(resolve, reject){ "use strict";
return new Promise(function(resolve){
process.stdout.write(prompt); process.stdout.write(prompt);
process.stdin.setEncoding('utf8'); process.stdin.setEncoding("utf8");
process.stdin.resume(); process.stdin.resume();
process.stdin.on("data", function onData(data){ process.stdin.on("data", function onData(data){
process.stdin.removeListener("data", onData); process.stdin.removeListener("data", onData);
@ -47,18 +51,22 @@ async function getInput(prompt){
} }
async function askForTranslation(key){ async function askForTranslation(key){
"use strict";
const enData = en[key]; const enData = en[key];
console.log("English translation for", key, ":", enData.message); console.log("English translation for", key, ":", enData.message);
if (enData.description){ if (enData.description){
console.log("\nDescription:", enData.description); console.log("\nDescription:", enData.description);
} }
return await getInput("Please enter translation: "); return getInput("Please enter translation: ");
} }
async function translate(language){ async function translate(language){
"use strict";
const originalData = await loadTranslation(language); const originalData = await loadTranslation(language);
const data = {}; const data = {};
for (var i = 0; i < enKeys.length; i += 1){ for (let i = 0; i < enKeys.length; i += 1){
const key = enKeys[i]; const key = enKeys[i];
const oldData = originalData[key]; const oldData = originalData[key];
const enData = en[key]; const enData = en[key];
@ -76,5 +84,11 @@ async function translate(language){
} }
translate(language).then(function(data){ translate(language).then(function(data){
"use strict";
return saveTranslation(language, data); return saveTranslation(language, data);
}).catch(function(error){
"use strict";
console.error(error);
}); });

View File

@ -61,5 +61,12 @@
"**/.git/objects/**", "**/.git/objects/**",
".vscode", ".vscode",
".eslintrc.json" ".eslintrc.json"
] ],
"eslint.validate": [
"javascript",
"php",
"html"
],
"eslint.options": {"--ext": ".js,.html,.php"},
"eslint.lintTask.enable": true
} }

4
.vscode/tasks.json vendored
View File

@ -16,7 +16,9 @@
"command": "eslint" "command": "eslint"
}, },
"args": [ "args": [
"./" "./",
"--ext",
".js,.html,.php"
], ],
"presentation": { "presentation": {
"echo": true, "echo": true,

6
codebeatsettings Normal file
View File

@ -0,0 +1,6 @@
{
"JAVASCRIPT": {
"LOC": [70, 80, 100, 120],
"BLOCK_NESTING": [4, 5, 6, 7]
}
}

View File

@ -97,7 +97,14 @@
"name": "clearPersistentRnd", "name": "clearPersistentRnd",
"actions": [ "actions": [
"clearPersistentRnd", "clearPersistentRnd",
browser.contextualIdentities? "clearPersistentRndForContainer": false function(){
try {
return browser.contextualIdentities? "clearPersistentRndForContainer": false;
}
catch (error){
return false;
}
}()
], ],
"displayDependencies": [ "displayDependencies": [
{ {

View File

@ -112,6 +112,7 @@
} }
function getIsPointInPath(ctx){ function getIsPointInPath(ctx){
"use strict"; "use strict";
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(20, 19); ctx.moveTo(20, 19);
ctx.lineTo(40, 19); ctx.lineTo(40, 19);
@ -120,8 +121,10 @@
ctx.stroke(); ctx.stroke();
return ctx.isPointInPath(30, 19); return ctx.isPointInPath(30, 19);
}; }
function hashToString(hash){ function hashToString(hash){
"use strict";
var chunks = []; var chunks = [];
(new Uint32Array(hash)).forEach(function(num){ (new Uint32Array(hash)).forEach(function(num){
chunks.push(num.toString(16)); chunks.push(num.toString(16));
@ -130,35 +133,41 @@
return "0".repeat(8 - chunk.length) + chunk; return "0".repeat(8 - chunk.length) + chunk;
}).join(""); }).join("");
} }
function send(form, {url, imageData, isPointInPath}){ var send = function(){
var buffer = new TextEncoder("utf-8").encode(url); "use strict";
Promise.all([ return function send(form, {url, imageData, isPointInPath}){
crypto.subtle.digest("SHA-256", buffer), var buffer = new TextEncoder("utf-8").encode(url);
crypto.subtle.digest("SHA-256", imageData.data) Promise.all([
]).then(function(hashes){ crypto.subtle.digest("SHA-256", buffer),
var data = JSON.stringify({ crypto.subtle.digest("SHA-256", imageData.data)
urlHash: hashToString(hashes[0]), ]).then(function(hashes){
imageDataHash: hashToString(hashes[1]), var data = JSON.stringify({
isPointInPath urlHash: hashToString(hashes[0]),
}, null, "\t"); imageDataHash: hashToString(hashes[1]),
form.fingerprint.value = data; isPointInPath
var xhr = new XMLHttpRequest(); }, null, "\t");
xhr.open("POST", form.action + "?main", true); form.fingerprint.value = data;
xhr.onreadystatechange = function(){ var xhr = new XMLHttpRequest();
if (this.readyState === 4){ xhr.open("POST", form.action + "?main", true);
const status = this.status; xhr.onreadystatechange = function(){
if (status === 200 || status === 304) { if (this.readyState === 4){
console.log("Sending xhr successful from main page:", data); const status = this.status;
if (status === 200 || status === 304) {
console.log("Sending xhr successful from main page:", data);
}
else {
console.log("Sending xhr failed:", this);
}
} }
else { };
console.log("Sending xhr failed:", this); xhr.send(new FormData(form));
} return;
} }).catch(function(error){
}; console.error(error);
xhr.send(new FormData(form)); });
}); };
} }();
send(document.getElementById("form"), topTest()); send(document.getElementById("form"), topTest());
</script> </script>

View File

@ -18,7 +18,6 @@ var addTest = (function(){
status = func(log)? 1: 2; status = func(log)? 1: 2;
} }
catch (error){ catch (error){
// eslint-disable-next-line no-console
console.log(error); console.log(error);
status = 3; status = 3;
} }

View File

@ -1,2 +1 @@
// eslint-disable-next-line no-console
console.log("first possible call"); console.log("first possible call");

View File

@ -13,35 +13,91 @@
const iframe = window[0]; const iframe = window[0];
log("TEST:", "iframe in html:", compare(test(iframe), reference)); log("TEST:", "iframe in html:", compare(test(iframe), reference));
iframe.addEventListener("load", function(){ iframe.addEventListener("load", function(){
"use strict";
log("TEST:", "iframe after loading:", compare(test(iframe), reference)); log("TEST:", "iframe after loading:", compare(test(iframe), reference));
}); });
document.write("<iframe></iframe><script>log(\"TEST:\", \"iframe and script in document.write:\", compare(test(window[1]), reference));<\/script>"); document.write(
"<iframe></iframe>" +
"<script>log(\"TEST:\", \"iframe and script in document.write:\", compare(test(window[1]), reference));<\/script>"
);
log("TEST:", "iframe in document.write:", compare(test(window[1]), reference)); log("TEST:", "iframe in document.write:", compare(test(window[1]), reference));
document.write("<iframe></iframe>"); document.write("<iframe></iframe>");
document.write("<script>log(\"TEST:\", \"iframe and script in separate document.write:\", compare(test(window[2]), reference));<\/script>"); document.write(
"<iframe></iframe><script>log(\"TEST:\", \"iframe and script in fragmented document.write:\", compare(test(window[3]), reference));<\/script>".split(/(?=<)/).forEach(function(part){ "<script>" +
"log(\"TEST:\", \"iframe and script in separate document.write:\", compare(test(window[2]), reference));" +
"<\/script>");
(
"<iframe></iframe>" +
"<script>" +
"log(\"TEST:\", \"iframe and script in fragmented document.write:\", compare(test(window[3]), reference));" +
"<\/script>"
).split(/(?=<)/).forEach(function(part){
"use strict";
document.write(part); document.write(part);
}); });
document.writeln("<iframe></iframe><script>log(\"TEST:\", \"iframe and script in document.writeln:\", compare(test(window[4]), reference));<\/script>"); document.writeln(
document.write("<script src=\"iframeTest.js\"><\/script><iframe></iframe><script>log(\"TEST:\", \"script with src, iframe and script in document.write:\", compare(test(window[5]), reference));<\/script>"); "<iframe></iframe>" +
"<script>log(\"TEST:\", \"iframe and script in document.writeln:\", compare(test(window[4]), reference));<\/script>"
);
document.write(
"<script src=\"iframeTest.js\"><\/script>" +
"<iframe></iframe>" +
"<script>" +
"log(" +
"\"TEST:\", " +
"\"script with src, iframe and script in document.write:\", " +
"compare(test(window[5]), reference)" +
");" +
"<\/script>"
);
"<ifr|ame></ifr|ame>".split("|").forEach(function(part){ "<ifr|ame></ifr|ame>".split("|").forEach(function(part){
"use strict";
document.write(part); document.write(part);
}); });
document.write("<script>log(\"TEST:\", \"ifr|ame split:\", compare(test(window[6]), reference));<\/script>"); document.write("<script>log(\"TEST:\", \"ifr|ame split:\", compare(test(window[6]), reference));<\/script>");
window.addEventListener("load", function(){ window.addEventListener("load", function(){
"use strict";
// document.open(); // document.open();
"<ifr|ame></ifr|ame>".split("|").forEach(function(part){ "<ifr|ame></ifr|ame>".split("|").forEach(function(part){
document.write(part); document.write(part);
}); });
document.write("<script>log(\"TEST:\", \"reopened document: ifr|ame split:\", compare(test(window[0]), reference));<\/script>"); document.write(
document.write("<script src=\"iframeTest.js\"><\/script><iframe></iframe><script>log(\"TEST:\", \"reopened document: script with src, iframe and script in document.write:\", compare(test(window[1]), reference, true));<\/script>"); "<script>" +
"log(\"TEST:\", \"reopened document: ifr|ame split:\", compare(test(window[0]), reference));" +
"<\/script>");
document.write(
"<script src=\"iframeTest.js\"><\/script>" +
"<iframe></iframe>" +
"<script>" +
"log(" +
"\"TEST:\", " +
"\"reopened document: script with src, iframe and script in document.write:\", " +
"compare(test(window[1]), reference, true)" +
");" +
"<\/script>"
);
// document.close(); // document.close();
}); });
window.setTimeout(function(){ window.setTimeout(function(){
"use strict";
document.body.innerHTML = "<iframe></iframe>"; document.body.innerHTML = "<iframe></iframe>";
console.log("TEST:", "innerHTML after 1000ms:", compare(test(window[0]), reference)); console.log("TEST:", "innerHTML after 1000ms:", compare(test(window[0]), reference));
document.body.innerHTML = "<h1>Iframe protection</h1>Open console (Ctrl + Shift + K) to see results. Depending on your Browser version you might have to check the \"Persist Logs\" flag and reload the page.<br><h2>Expected result</h2><ul><li>the displayed hashes should not be your native hash (run test with CB disabled to get it)</li><li>all the displayed hashes should be the same (exception if there is a change to a wyciwyg page)</li><li>all lines with \"TEST:\" should have a \"match\" at the end</li></ul>"; document.body.innerHTML = "<h1>Iframe protection</h1>" +
"Open console (Ctrl + Shift + K) to see results. " +
"Depending on your Browser version you might have to check the \"Persist Logs\" flag and reload the page.<br>" +
"<h2>Expected result</h2>" +
"<ul>" +
"<li>the displayed hashes should not be your native hash (run test with CB disabled to get it)</li>" +
"<li>all the displayed hashes should be the same (exception if there is a change to a wyciwyg page)</li>" +
"<li>all lines with \"TEST:\" should have a \"match\" at the end</li>" +
"</ul>";
var title = document.createElement("title"); var title = document.createElement("title");
title.textContent = "iFrame test"; title.textContent = "iFrame test";
document.getElementsByTagName("head")[0].appendChild(title); document.getElementsByTagName("head")[0].appendChild(title);

View File

@ -9,7 +9,6 @@ var log = function(){
str.unshift("color: red"); str.unshift("color: red");
str.unshift("%cX"); str.unshift("%cX");
} }
// eslint-disable-next-line no-console
console.log(...str); console.log(...str);
}; };
}(); }();
@ -67,7 +66,6 @@ function compare(string1, string2, alwaysOutputHashes){
hash(string1), hash(string1),
hash(string2) hash(string2)
]).then(function(hashes){ ]).then(function(hashes){
// eslint-disable-next-line no-console
console.log(message, ...hashes); console.log(message, ...hashes);
return; return;
}); });

View File

@ -22,7 +22,9 @@ var createLog = function(){
var log = createLog(); var log = createLog();
log("user agent equal between server and client: " + (window.serverUserAgent === navigator.userAgent)); log("user agent equal between server and client: " + (
document.getElementById("serverUserAgent").text === navigator.userAgent
));
Object.keys(navigator.__proto__).sort().forEach(function(property){ Object.keys(navigator.__proto__).sort().forEach(function(property){
"use strict"; "use strict";

View File

@ -23,8 +23,6 @@ Tests the navigator properties. In the default settings of CanvasBlocker the nav
</div> </div>
</div> </div>
</div> </div>
<script> <script id="serverUserAgent" type="text/data"><?php echo htmlentities($_SERVER["HTTP_USER_AGENT"], ENT_QUOTES, "UTF-8");?></script>
var serverUserAgent = <?php echo json_encode($_SERVER["HTTP_USER_AGENT"]);?>;
</script>
<script src="navigatorTest.js"></script> <script src="navigatorTest.js"></script>
</body></html> </body></html>

View File

@ -52,8 +52,10 @@
ctx.stroke(); ctx.stroke();
return ctx.isPointInPath(30, 19); return ctx.isPointInPath(30, 19);
}; }
function hashToString(hash){ function hashToString(hash){
"use strict";
var chunks = []; var chunks = [];
(new Uint32Array(hash)).forEach(function(num){ (new Uint32Array(hash)).forEach(function(num){
chunks.push(num.toString(16)); chunks.push(num.toString(16));
@ -63,42 +65,49 @@
}).join(""); }).join("");
} }
function send(form, {url, imageData, isPointInPath}){ var send = function(){
var buffer = new TextEncoder("utf-8").encode(url); "use strict";
Promise.all([
crypto.subtle.digest("SHA-256", buffer), return function send(form, {url, imageData, isPointInPath}){
crypto.subtle.digest("SHA-256", imageData.data) var buffer = new TextEncoder("utf-8").encode(url);
]).then(function(hashes){ return Promise.all([
var data = JSON.stringify({ crypto.subtle.digest("SHA-256", buffer),
urlHash: hashToString(hashes[0]), crypto.subtle.digest("SHA-256", imageData.data)
imageDataHash: hashToString(hashes[1]), ]).then(function(hashes){
isPointInPath var data = JSON.stringify({
}, null, "\t"); urlHash: hashToString(hashes[0]),
form.fingerprint.value = data; imageDataHash: hashToString(hashes[1]),
var xhr = new XMLHttpRequest(); isPointInPath
xhr.open("POST", form.action, true); }, null, "\t");
xhr.onreadystatechange = function(){ form.fingerprint.value = data;
if (this.readyState === 4){ var xhr = new XMLHttpRequest();
const status = this.status; xhr.open("POST", form.action, true);
if (status === 200 || status === 304) { xhr.onreadystatechange = function(){
console.log("Sending xhr successful from", origin, ":", data); if (this.readyState === 4){
const status = this.status;
if (status === 200 || status === 304) {
console.log("Sending xhr successful from", origin, ":", data);
}
else {
console.log("Sending xhr failed:", this);
}
} }
else { };
console.log("Sending xhr failed:", this); xhr.send(new FormData(form));
}
}
};
xhr.send(new FormData(form));
window.setTimeout(function(){
form.submit();
window.setTimeout(function(){ window.setTimeout(function(){
document.getElementById("log").textContent = "You see the real canvas fingerprint, but it cannot leak from this iFrame."; form.submit();
}, window.setTimeout(
250 function(){
); document.getElementById("log").textContent =
}, 1000); "You see the real canvas fingerprint, but it cannot leak from this iFrame.";
}); },
} 250
);
}, 1000);
return;
});
};
}();
send(document.getElementById("form"), topTest()); send(document.getElementById("form"), topTest());
</script> </script>

View File

@ -28,6 +28,8 @@
return canvas.toDataURL(); return canvas.toDataURL();
} }
function hash(url){ function hash(url){
"use strict";
var buffer = new TextEncoder("utf-8").encode(url); var buffer = new TextEncoder("utf-8").encode(url);
return crypto.subtle.digest("SHA-256", buffer).then(function(hash){ return crypto.subtle.digest("SHA-256", buffer).then(function(hash){
var chunks = []; var chunks = [];
@ -39,12 +41,12 @@
}).join(""); }).join("");
}); });
} }
var firstFingerprint = false;
try { try {
var firstFingerprint = fingerPrint(); firstFingerprint = fingerPrint();
} }
catch (error){ catch (error){
console.log(new Date(), error); console.log(new Date(), error);
var firstFingerprint = false;
} }
</script> </script>
<style> <style>
@ -67,19 +69,29 @@
var output = document.getElementById("output"); var output = document.getElementById("output");
output.textContent = "context API not blocked"; output.textContent = "context API not blocked";
window.setTimeout(function(){ window.setTimeout(function(){
"use strict";
console.log(new Date(), "starting second fingerprint", window.name); console.log(new Date(), "starting second fingerprint", window.name);
output.appendChild(document.createElement("br")); output.appendChild(document.createElement("br"));
var secondFingerprint = fingerPrint(); var secondFingerprint = fingerPrint();
if (firstFingerprint === secondFingerprint){ if (firstFingerprint === secondFingerprint){
hash(firstFingerprint).then(function(hash){ return hash(firstFingerprint).then(function(hash){
output.appendChild(document.createTextNode("fingerprint consistent (" + hash + ") -> good!")); output.appendChild(document.createTextNode("fingerprint consistent (" + hash + ") -> good!"));
output.style.backgroundColor = "green"; output.style.backgroundColor = "green";
return;
}); });
} }
else { else {
Promise.all([hash(firstFingerprint), hash(secondFingerprint)]).then(function(hashes){ return Promise.all([hash(firstFingerprint), hash(secondFingerprint)]).then(function(hashes){
output.appendChild(document.createTextNode("fingerprint not consistent (" + hashes[0] + " != " + hashes[1] + ") -> very bad! (potential fingerprint leak)")); output.appendChild(
document.createTextNode(
"fingerprint not consistent (" +
hashes[0] + " != " + hashes[1] +
") -> very bad! (potential fingerprint leak)"
)
);
output.style.backgroundColor = "red"; output.style.backgroundColor = "red";
return;
}); });
} }
}, 500); }, 500);

View File

@ -32,25 +32,18 @@
if (location.search !== "?notInitial"){ if (location.search !== "?notInitial"){
try {show(document.getElementById("top"), topTest());} try {show(document.getElementById("top"), topTest());}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
try {show(document.getElementById("iframe"), iframeTest(document.querySelector("#iframe iframe")));} try {show(document.getElementById("iframe"), iframeTest(document.querySelector("#iframe iframe")));}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
try {show(document.getElementById("iframe2"), iframeTest(document.querySelector("#iframe2 iframe")));} try {show(document.getElementById("iframe2"), iframeTest(document.querySelector("#iframe2 iframe")));}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
try {show(document.getElementById("iframe3"), iframeTest(document.querySelector("#iframe3 iframe")));} try {show(document.getElementById("iframe3"), iframeTest(document.querySelector("#iframe3 iframe")));}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
try {show(document.getElementById("iframe4"), dynamicIframeTest1());} try {show(document.getElementById("iframe4"), dynamicIframeTest1());}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
try {show(document.getElementById("iframe5"), dynamicIframeTest2());} try {show(document.getElementById("iframe5"), dynamicIframeTest2());}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
try {show(document.getElementById("iframe6"), dynamicIframeTest3());} try {show(document.getElementById("iframe6"), dynamicIframeTest3());}
// eslint-disable-next-line no-console
catch (error){console.error(error);} catch (error){console.error(error);}
} }
document.querySelector("#top button").addEventListener("click", function(){ document.querySelector("#top button").addEventListener("click", function(){