| |
@@ -134,6 +134,10 @@
|
| |
template.url = url;
|
| |
template.site = ListStore.siteItem(url);
|
| |
template.siteStatus = listManager.getStatus(template.site);
|
| |
+ let list = {"whitelisted": whitelist, "blacklisted": blacklist}[template.siteStatus];
|
| |
+ if (list) {
|
| |
+ template.listedSite = ListManager.siteMatch(template.site, list);
|
| |
+ }
|
| |
return template;
|
| |
}
|
| |
|
| |
@@ -326,7 +330,7 @@
|
| |
if (m[action]) {
|
| |
let [key] = m[action];
|
| |
if (m.site) {
|
| |
- key = ListStore.siteItem(key);
|
| |
+ key = ListStore.siteItem(m.site);
|
| |
} else {
|
| |
key = ListStore.inlineItem(key) || key;
|
| |
}
|
| |
@@ -745,12 +749,12 @@
|
| |
let scriptName = url.split("/").pop();
|
| |
if (whitelisted) {
|
| |
if (tabId !== -1) {
|
| |
- let site = ListStore.siteItem(url);
|
| |
+ let site = ListManager.siteMatch(url, whitelist);
|
| |
// Accept without reading script, it was explicitly whitelisted
|
| |
- let reason = whitelist.contains(site)
|
| |
+ let reason = site
|
| |
? `All ${site} whitelisted by user`
|
| |
: "Address whitelisted by user";
|
| |
- addReportEntry(tabId, url, {"whitelisted": [url, reason], url});
|
| |
+ addReportEntry(tabId, url, {"whitelisted": [site || url, reason], url});
|
| |
}
|
| |
if (response.startsWith("javascript:"))
|
| |
return result(response);
|
| |
@@ -801,42 +805,28 @@
|
| |
}
|
| |
}
|
| |
|
| |
- /**
|
| |
- * Tests if a request is google analytics or not
|
| |
- */
|
| |
- function test_GA(a){ // TODO: DRY me
|
| |
- // This is just an HTML page
|
| |
- if(a.url == 'https://www.google.com/analytics/#?modal_active=none'){
|
| |
- return false;
|
| |
- }
|
| |
- else if(a.url.match(/https:\/\/www\.google\.com\/analytics\//g)){
|
| |
- dbg_print("%c Google analytics (1)","color:red");
|
| |
- return {cancel: true};
|
| |
+ function blockGoogleAnalytics(request) {
|
| |
+ let {url} = request;
|
| |
+ let res = {};
|
| |
+ if (url === 'https://www.google-analytics.com/analytics.js' ||
|
| |
+ /^https:\/\/www\.google\.com\/analytics\/[^#]/.test(url)
|
| |
+ ) {
|
| |
+ res.cancel = true;
|
| |
}
|
| |
- else if(a.url == 'https://www.google-analytics.com/analytics.js'){
|
| |
- dbg_print("%c Google analytics (2)","color:red");
|
| |
- return {cancel: true};
|
| |
- }
|
| |
- else if(a.url == 'https://www.google.com/analytics/js/analytics.min.js'){
|
| |
- dbg_print("%c Google analytics (3)","color:red");
|
| |
- return {cancel: true};
|
| |
- }
|
| |
- else return false;
|
| |
+ return res;
|
| |
}
|
| |
|
| |
- /**
|
| |
- * A callback that every type of request invokes.
|
| |
- */
|
| |
- function block_ga(a){
|
| |
- var GA = test_GA(a);
|
| |
- if(GA != false){
|
| |
- return GA;
|
| |
- }
|
| |
- else return {};
|
| |
+ async function blockBlacklistedScripts(request) {
|
| |
+ let {url, tabId, documentUrl} = request;
|
| |
+ url = ListStore.urlItem(url);
|
| |
+ let status = listManager.getStatus(url);
|
| |
+ if (status !== "blacklisted") return {};
|
| |
+ let blacklistedSite = ListManager.siteMatch(url, blacklist);
|
| |
+ await addReportEntry(tabId, url, {url: documentUrl,
|
| |
+ "blacklisted": [url, /\*/.test(blacklistedSite) ? `User blacklisted ${blacklistedSite}` : "Blacklisted by user"]});
|
| |
+ return {cancel: true};
|
| |
}
|
| |
|
| |
-
|
| |
-
|
| |
/**
|
| |
* This listener gets called as soon as we've got all the HTTP headers, can guess
|
| |
* content type and encoding, and therefore correctly parse HTML documents
|
| |
@@ -855,30 +845,37 @@
|
| |
url = ListStore.urlItem(url);
|
| |
let site = ListStore.siteItem(url);
|
| |
|
| |
- let blacklistedSite = blacklist.contains(site);
|
| |
+ let blacklistedSite = ListManager.siteMatch(site, blacklist);
|
| |
let blacklisted = blacklistedSite || blacklist.contains(url);
|
| |
- let topUrl = request.frameAncestors && request.frameAncestors.pop() || documentUrl;
|
| |
+ let topUrl = type === "sub_frame" && request.frameAncestors && request.frameAncestors.pop() || documentUrl;
|
| |
|
| |
if (blacklisted) {
|
| |
if (type === "script") {
|
| |
- // abort the request before the response gets fetched
|
| |
- addReportEntry(tabId, url, {url: topUrl,
|
| |
- "blacklisted": [url, blacklistedSite ? `User blacklisted ${site}` : "Blacklisted by user"]});
|
| |
+ // this shouldn't happen, because we intercept earlier in blockBlacklistedScripts()
|
| |
return ResponseProcessor.REJECT;
|
| |
}
|
| |
+ if (type === "main_frame") { // we handle the page change here too, since we won't call edit_html()
|
| |
+ activityReports[tabId] = await createReport({url: fullUrl, tabId});
|
| |
+ // Go on without parsing the page: it was explicitly blacklisted
|
| |
+ let reason = blacklistedSite
|
| |
+ ? `All ${blacklistedSite} blacklisted by user`
|
| |
+ : "Address blacklisted by user";
|
| |
+ await addReportEntry(tabId, url, {"blacklisted": [blacklistedSite || url, reason], url: fullUrl});
|
| |
+ }
|
| |
// use CSP to restrict JavaScript execution in the page
|
| |
request.responseHeaders.unshift({
|
| |
name: `Content-security-policy`,
|
| |
- value: `script-src '${blacklistedSite ? 'self' : 'none'}';`
|
| |
+ value: `script-src 'none';`
|
| |
});
|
| |
+ return {responseHeaders: request.responseHeaders}; // let's skip the inline script parsing, since we block by CSP
|
| |
} else {
|
| |
- let whitelistedSite = whitelist.contains(site);
|
| |
+ let whitelistedSite = ListManager.siteMatch(site, whitelist);
|
| |
let whitelisted = response.whitelisted = whitelistedSite || whitelist.contains(url);
|
| |
if (type === "script") {
|
| |
if (whitelisted) {
|
| |
// accept the script and stop processing
|
| |
addReportEntry(tabId, url, {url: topUrl,
|
| |
- "whitelisted": [url, whitelistedSite ? `User whitelisted ${site}` : "Whitelisted by user"]});
|
| |
+ "whitelisted": [url, whitelistedSite ? `User whitelisted ${whitelistedSite}` : "Whitelisted by user"]});
|
| |
return ResponseProcessor.ACCEPT;
|
| |
} else {
|
| |
let scriptInfo = await ExternalLicenses.check({url: fullUrl, tabId, frameId, documentUrl});
|
| |
@@ -1189,11 +1186,21 @@
|
| |
"web_manifest", "websocket", "xbl", "xml_dtd", "xmlhttprequest", "xslt",
|
| |
"other"
|
| |
];
|
| |
- browser.webRequest.onBeforeRequest.addListener(
|
| |
- block_ga,
|
| |
+ browser.webRequest.onBeforeRequest.addListener(blockGoogleAnalytics,
|
| |
{urls: ["<all_urls>"], types: all_types},
|
| |
["blocking"]
|
| |
);
|
| |
+ browser.webRequest.onBeforeRequest.addListener(blockBlacklistedScripts,
|
| |
+ {urls: ["<all_urls>"], types: ["script"]},
|
| |
+ ["blocking"]
|
| |
+ );
|
| |
+ browser.webRequest.onResponseStarted.addListener(request => {
|
| |
+ let {tabId} = request;
|
| |
+ let report = activityReports[tabId];
|
| |
+ if (report) {
|
| |
+ updateBadge(tabId, activityReports[tabId]);
|
| |
+ }
|
| |
+ }, {urls: ["<all_urls>"], types: ["main_frame"]});
|
| |
|
| |
// Analyzes all the html documents and external scripts as they're loaded
|
| |
ResponseProcessor.install(ResponseHandler);
|
| |
@@ -1208,6 +1215,7 @@
|
| |
editHtml,
|
| |
handle_script,
|
| |
ExternalLicenses,
|
| |
+ ListManager, ListStore, Storage,
|
| |
};
|
| |
// create or focus the autotest tab if it's a debugging session
|
| |
if ((await browser.management.getSelf()).installType === "development") {
|
| |
Adds support for wildcarding subdomains and/or paths (e.g. https://*.gnu.org/* would match any .gnu.org domain, no matter the path), both in the back-end and in the front-end (main panel and preference panel).
Includes testing for whitelisting and blacklisting with support for wildcards.
Fixed some asynchronous call bugs along the way, discovered running the newly added automated tests :)