Work-around for serviceWorker loads bypassing webRequest.

This commit is contained in:
hackademix 2018-07-24 23:21:01 +02:00
parent ec79210bd1
commit 8d6f963022
2 changed files with 54 additions and 19 deletions

View File

@ -72,6 +72,7 @@ var RequestGuard = (() => {
},
initTab(tabId, records = this.newRecords()) {
if (tabId < 0) return;
this.map.set(tabId, records);
return records;
},
@ -109,6 +110,8 @@ var RequestGuard = (() => {
},
record(request, what, optValue) {
let {tabId} = request;
if (tabId < 0) return;
let records = this._record(request, what, optValue);
if (records) {
this.updateTab(request.tabId);
@ -118,6 +121,7 @@ var RequestGuard = (() => {
_pendingTabs: new Set(),
updateTab(tabId) {
if (tabId < 0) return;
if (this._pendingTabs.size === 0) {
window.setTimeout(() => { // clamp UI updates
for (let tabId of this._pendingTabs) {
@ -217,7 +221,7 @@ var RequestGuard = (() => {
case "pageshow":
TabStatus.recordAll(sender.tab.id, message.seen);
return true;
case "enable":
case "enable": {
let {url, documentUrl, policyType} = message;
let TAG = `<${policyType.toUpperCase()}>`;
let origin = Sites.origin(url);
@ -258,10 +262,17 @@ var RequestGuard = (() => {
ns.savePolicy();
}
return true;
case "canScript":
let records = TabStatus.map.get(sender.tab.id);
debug("Records.noscriptFrames %o, canScript: %s", records && records.noscriptFrames, !(records && records.noscriptFrames[sender.frameId]));
return !(records && records.noscriptFrames[sender.frameId]);
}
case "canScript": {
let {frameId, url, tab} = sender;
let tabId = tab.id;
let records = TabStatus.map.get(tabId);
let noscriptFrames = records && records.noscriptFrames;
let canScript = !(noscriptFrames && noscriptFrames[sender.frameId]);
let shouldScript = ns.isEnforced(tabId) && ns.policy.can(url, "script");
debug("Frame %s %s of %o, canScript: %s, shouldScript: %s", frameId, url, noscriptFrames, canScript, shouldScript);
return {canScript, shouldScript};
}
}
},

View File

@ -1,7 +1,9 @@
'use strict';
// debug = () => {}; // XPI_ONLY
window.canScript = true;
function createHTMLElement(name) {
return document.createElementNS("http://www.w3.org/1999/xhtml", name);
}
@ -20,7 +22,6 @@ function probe() {
var _ = browser.i18n.getMessage;
var canScript = true;
var embeddingDocument = false;
@ -86,26 +87,49 @@ let notifyPage = () => {
}
var queryingCanScript = false;
var caps = {};
async function init(oldPage = false) {
if (queryingCanScript) return;
if (document.URL === "about:blank") {
return;
}
queryingCanScript = true;
debug(`NoScript init() called in document %s, scripting=%s, content type %s readyState %s`,
document.URL, canScript, document.contentType, document.readyState);
debug(`init() called in document %s, contentType %s readyState %s`,
document.URL, document.contentType, document.readyState);
try {
canScript = document.URL === "about:blank" || await browser.runtime.sendMessage({type: "canScript"});
if (oldPage && canScript) {
probe();
setTimeout(() => init(), 100);
return;
let {canScript, shouldScript} = await browser.runtime.sendMessage({type: "canScript"});
debug(`document %s, canScript=%s, shouldScript=%s, readyState %s`, document.URL, canScript, shouldScript, document.readyState);
if (canScript) {
if (oldPage) {
probe();
setTimeout(() => init(), 100);
return;
}
if (!shouldScript) {
// Something wrong: scripts can run, permissions say they shouldn't.
// Was webRequest bypassed by caching/session restore/service workers?
let noCache = !!navigator.serviceWorker.controller;
if (noCache) {
for (let r of await navigator.serviceWorker.getRegistrations()) {
await r.unregister();
}
}
debug("Reloading %s (%s)", document.URL, noCache ? "no cache" : "cached");
location.reload(noCache);
return;
}
}
window.canScript = canScript;
init = () => {};
debug("canScript:", canScript);
} catch (e) {
debug("Error querying canScript", e);
if (document.readyState !== "complete" &&
if (!oldPage &&
/Receiving end does not exist/.test(e.message)) {
window.location.reload(false);
// probably startup and bg page not ready yet, hence no CSP: reload!
location.reload(false);
} else {
setTimeout(() => init(oldPage), 100);
}
@ -126,8 +150,8 @@ async function init(oldPage = false) {
}
);
debug(`Loading NoScript in document %s, scripting=%s, content type %s readyState %s`,
document.URL, canScript, document.contentType, document.readyState);
debug(`Loading NoScript in document %s, scripting=%s, readyState %s`,
document.URL, canScript, document.readyState);
if (/application|video|audio/.test(document.contentType)) {
debug("Embedding document detected");