diff --git a/.documentation/addon description/de/description.txt b/.documentation/addon description/de/description.txt index 61aa60d..0ac42b2 100644 --- a/.documentation/addon description/de/description.txt +++ b/.documentation/addon description/de/description.txt @@ -19,6 +19,7 @@ Geschützte "Fingerprinting"-APIs:
  • webGL
  • audio
  • history
  • +
  • window (standardmäßig deaktiviert)
  • Falls Sie Fehler finden oder Verbesserungsvorschläge haben, teilen Sie mir das bitte auf https://github.com/kkapsner/CanvasBlocker/issues mit. \ No newline at end of file diff --git a/.documentation/addon description/en/description.txt b/.documentation/addon description/en/description.txt index 2dcb180..d52d667 100644 --- a/.documentation/addon description/en/description.txt +++ b/.documentation/addon description/en/description.txt @@ -19,6 +19,7 @@ Protected "fingerprinting" APIs:
  • webGL
  • audio
  • history
  • +
  • window (disabled by default)
  • Please report issues and feature requests at https://github.com/kkapsner/CanvasBlocker/issues diff --git a/_locales/de/messages.json b/_locales/de/messages.json index 1e00553..bee7e80 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -97,6 +97,10 @@ "message": "History API", "description": "" }, + "section_window-api":{ + "message": "Window API", + "description": "" + }, "displayAdvancedSettings_title": { "message": "Expertenmodus", @@ -193,6 +197,18 @@ "message": "Wollen Sie das Auslesen über die History-API erlauben?", "description": "" }, + "askForWindowPermission": { + "message": "Wollen Sie die Window-API erlauben?", + "description": "" + }, + "askForWindowInputPermission": { + "message": "Wollen Sie das Schreiben in über die Window-API erlauben?", + "description": "" + }, + "askForWindowReadoutPermission": { + "message": "Wollen Sie das Auslesen über die Window-API erlauben?", + "description": "" + }, "askOnlyOnce_title": { "message": "Nur einmal nachfragen", "description": "" @@ -520,6 +536,10 @@ "message": "History-Auslese vorgetäuscht auf {url}", "description": "" }, + "fakedWindowReadout": { + "message": "Window-Auslese vorgetäuscht auf {url}", + "description": "" + }, "fakedInput": { "message": "Bei Ausgabe vorgetäuscht auf {url}", "description": "" @@ -833,6 +853,15 @@ "description": "" }, + "protectWindow_title": { + "message": "Window-API beschützen", + "description": "" + }, + "protectWindow_description": { + "message": "Es werden window.opener und window.name beschützt. Dies kann manche Webseiten unbrauchbar machen.", + "description": "" + }, + "theme_title": { "message": "Theme", "description": "" diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 9272887..2c457ae 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -97,6 +97,10 @@ "message": "History API", "description": "" }, + "section_window-api":{ + "message": "Window API", + "description": "" + }, "displayAdvancedSettings_title": { "message": "Expert mode", @@ -193,6 +197,18 @@ "message": "Do you want to allow history readout?", "description": "" }, + "askForWindowPermission": { + "message": "Do you want to allow the window API?", + "description": "" + }, + "askForWindowInputPermission": { + "message": "Do you want to allow window-API input?", + "description": "" + }, + "askForWindowReadoutPermission": { + "message": "Do you want to allow window readout?", + "description": "" + }, "askOnlyOnce_title": { "message": "Ask only once", "description": "" @@ -520,6 +536,10 @@ "message": "Faked history readout on {url}", "description": "" }, + "fakedWindowReadout": { + "message": "Faked window readout on {url}", + "description": "" + }, "fakedInput": { "message": "Faked at input on {url}", "description": "" @@ -832,6 +852,15 @@ "description": "" }, + "protectWindow_title": { + "message": "Protect Window API", + "description": "" + }, + "protectWindow_description": { + "message": "window.opener and window.name will be protected. This can render some web pages unusable.", + "description": "" + }, + "theme_title": { "message": "Theme", "description": "" diff --git a/lib/askForPermission.js b/lib/askForPermission.js index bc2c7b0..c494609 100644 --- a/lib/askForPermission.js +++ b/lib/askForPermission.js @@ -88,6 +88,7 @@ nocanvas: _("askForPermission"), audio: _("askForAudioPermission"), history: _("askForHistoryPermission"), + window: _("askForWindowPermission") }, askStatus: { alreadyAsked: {}, @@ -101,6 +102,7 @@ nocanvas: _("askForInputPermission"), audio: _("askForAudioInputPermission"), history: _("askForHistoryInputPermission"), + window: _("askForWindowInputPermission") }, askStatus: { alreadyAsked: {}, @@ -114,6 +116,7 @@ nocanvas: _("askForReadoutPermission"), audio: _("askForAudioReadoutPermission"), history: _("askForHistoryReadoutPermission"), + window: _("askForWindowReadoutPermission") }, askStatus: { alreadyAsked: {}, diff --git a/lib/modifiedAPI.js b/lib/modifiedAPI.js index 7149c1d..2d3accb 100644 --- a/lib/modifiedAPI.js +++ b/lib/modifiedAPI.js @@ -487,4 +487,5 @@ } appendModified(modifiedAudioAPI); appendModified(require("./modifiedHistoryAPI")); + appendModified(require("./modifiedWindowAPI")); }()); \ No newline at end of file diff --git a/lib/modifiedWindowAPI.js b/lib/modifiedWindowAPI.js new file mode 100644 index 0000000..aa0cbc0 --- /dev/null +++ b/lib/modifiedWindowAPI.js @@ -0,0 +1,87 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +(function(){ + "use strict"; + + var scope; + if ((typeof exports) !== "undefined"){ + scope = exports; + } + else { + window.scope.modifiedWindowAPI = {}; + scope = window.scope.modifiedWindowAPI; + } + + const {hasType, checkerWrapper} = require("./modifiedAPIFunctions"); + + const windowNames = new WeakMap(); + scope.changedGetters = [ + { + objectGetters: [function(window){return window;}], + name: "opener", + getterGenerator: function(checker){ + const temp = { + get opener(){ + return checkerWrapper(checker, this, arguments, function(args, check){ + const {prefs, notify, window, original} = check; + if (!prefs("protectWindow", window.location)){ + return original.apply(this, window.Array.from(args)); + } + const originalOpener = original.apply(this, window.Array.from(args)); + if (originalOpener !== null){ + notify("fakedWindowReadout"); + } + return null; + }); + } + }; + return Object.getOwnPropertyDescriptor(temp, "opener").get; + } + }, + { + objectGetters: [function(window){return window;}], + name: "name", + getterGenerator: function(checker){ + const temp = { + get name(){ + return checkerWrapper(checker, this, arguments, function(args, check){ + const {prefs, notify, window, original} = check; + if (!prefs("protectWindow", window.location)){ + return original.apply(this, window.Array.from(args)); + } + const originalName = original.apply(this, window.Array.from(args)); + const returnedName = windowNames.get(window) || ""; + if (originalName !== returnedName){ + notify("fakedWindowReadout"); + } + return returnedName; + }); + } + }; + return Object.getOwnPropertyDescriptor(temp, "name").get; + }, + setterGenerator: function(window, original){ + const temp = { + set name(name){ + original.apply(this, window.Array.from(arguments)); + windowNames.set(window, name); + } + }; + return Object.getOwnPropertyDescriptor(temp, "name").set; + } + } + ]; + + function getStatus(obj, status){ + status = Object.create(status); + status.active = hasType(status, "readout"); + return status; + } + + scope.changedGetters.forEach(function(changedGetter){ + changedGetter.type = "readout"; + changedGetter.getStatus = getStatus; + changedGetter.api = "window"; + }); +}()); \ No newline at end of file diff --git a/lib/settingDefinitions.js b/lib/settingDefinitions.js index 212fa1e..7533d9b 100644 --- a/lib/settingDefinitions.js +++ b/lib/settingDefinitions.js @@ -92,6 +92,9 @@ "getFrequencyResponse", {name: "History-API", level: 1}, "length", + {name: "Window-API", level: 1}, + "opener", + "name", ], defaultKeyValue: false }, @@ -191,6 +194,7 @@ "canvas", "audio", "history", + "window", ], defaultKeyValue: false }, @@ -243,6 +247,11 @@ name: "historyLengthThreshold", defaultValue: 2 }, + { + name: "protectWindow", + defaultValue: false, + urlSpecific: true + }, { name: "blockDataURLs", defaultValue: true diff --git a/manifest.json b/manifest.json index 1d8bfb1..149a25a 100644 --- a/manifest.json +++ b/manifest.json @@ -38,6 +38,7 @@ "lib/modifiedAPIFunctions.js", "lib/modifiedAudioAPI.js", "lib/modifiedHistoryAPI.js", + "lib/modifiedWindowAPI.js", "lib/modifiedAPI.js", "lib/randomSupplies.js", "lib/intercept.js", diff --git a/options/settingsDisplay.js b/options/settingsDisplay.js index 4f03593..b89d5b9 100644 --- a/options/settingsDisplay.js +++ b/options/settingsDisplay.js @@ -397,6 +397,13 @@ "displayAdvancedSettings": [true] } }, + "Window-API", + { + "name": "protectWindow", + "displayDependencies": { + "displayAdvancedSettings": [true] + } + }, "misc", { "name": "theme" diff --git a/releaseNotes.txt b/releaseNotes.txt index 76a1cea..0b3eed2 100644 --- a/releaseNotes.txt +++ b/releaseNotes.txt @@ -12,6 +12,7 @@ Version 0.5.3: - added badge - added option to ignore APIs - added protection for history length + - added protection for window name and opener fixes: - CSP did not work properly for worker-src diff --git a/test/detectionTest.js b/test/detectionTest.js index 6efc75a..77e3d10 100644 --- a/test/detectionTest.js +++ b/test/detectionTest.js @@ -118,6 +118,14 @@ addTest("function code", function(log){ history.__lookupGetter__("length"), "get length" ) || codeDetected; + codeDetected = checkFunctionCode( + window.__lookupGetter__("name"), + "get name" + ) || codeDetected; + codeDetected = checkFunctionCode( + window.__lookupSetter__("name"), + "set name" + ) || codeDetected; return codeDetected; }); addTest("toString modified", function(log){ @@ -395,4 +403,20 @@ addTest("readout - in - out test", function(log){ } } return false; +}); + +addTest("window name change", function(log){ + "use strict"; + + var oldName = window.name; + log("old name:", oldName); + var newName = oldName + " added"; + log("new name:", newName); + window.name = newName; + + if (window.name !== newName){ + log("window name not set:", window.name); + return true; + } + return false; }); \ No newline at end of file diff --git a/test/settingsLoading.php b/test/settingsLoading.php index 1d19a1e..9fde02c 100644 --- a/test/settingsLoading.php +++ b/test/settingsLoading.php @@ -3,7 +3,7 @@ Test