Added protection for window.name and window.opener

As requested by #231.

But this protection is disabled by default.
This commit is contained in:
kkapsner 2018-08-27 00:33:39 +02:00
parent fd7c4fabbd
commit 83efac5e49
13 changed files with 195 additions and 2 deletions

View File

@ -19,6 +19,7 @@ Geschützte "Fingerprinting"-APIs:
<li>webGL</li>
<li>audio</li>
<li>history</li>
<li>window (standardmäßig deaktiviert)</li>
</ul>
Falls Sie Fehler finden oder Verbesserungsvorschläge haben, teilen Sie mir das bitte auf https://github.com/kkapsner/CanvasBlocker/issues mit.

View File

@ -19,6 +19,7 @@ Protected "fingerprinting" APIs:
<li>webGL</li>
<li>audio</li>
<li>history</li>
<li>window (disabled by default)</li>
</ul>
Please report issues and feature requests at https://github.com/kkapsner/CanvasBlocker/issues

View File

@ -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": ""

View File

@ -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": ""

View File

@ -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: {},

View File

@ -487,4 +487,5 @@
}
appendModified(modifiedAudioAPI);
appendModified(require("./modifiedHistoryAPI"));
appendModified(require("./modifiedWindowAPI"));
}());

87
lib/modifiedWindowAPI.js Normal file
View File

@ -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";
});
}());

View File

@ -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

View File

@ -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",

View File

@ -397,6 +397,13 @@
"displayAdvancedSettings": [true]
}
},
"Window-API",
{
"name": "protectWindow",
"displayDependencies": {
"displayAdvancedSettings": [true]
}
},
"misc",
{
"name": "theme"

View File

@ -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

View File

@ -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;
});

View File

@ -3,7 +3,7 @@
<head>
<title>Test</title>
<script>
console.log(new Date(), "starting first fingerprint");
console.log(new Date(), "starting first fingerprint", window.name);
function fingerPrint(){
"use strict";var canvas = document.createElement("canvas");
canvas.setAttribute("width", 220);
@ -50,7 +50,7 @@
if (firstFingerprint){
document.body.textContent = "context API not blocked";
window.setTimeout(function(){
console.log(new Date(), "starting second fingerprint");
console.log(new Date(), "starting second fingerprint", window.name);
document.body.appendChild(document.createElement("br"));
var secondFingerprint = fingerPrint();
if (firstFingerprint === secondFingerprint){