From 5fd9b64960e3d8ca35031a115628077966c85647 Mon Sep 17 00:00:00 2001 From: hackademix Date: Tue, 15 Feb 2022 01:04:43 +0100 Subject: [PATCH] LAN capability to check for cross-zone WAN to LAN requests (thanks barbaz for ABE webext contributions). --- src/_locales/en/messages.json | 3 +++ src/bg/RequestGuard.js | 42 +++++++++++++++++++++++++---------- src/manifest.json | 4 ++++ src/nscl | 2 +- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 25614ec..44d4e82 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -563,6 +563,9 @@ "cap_unchecked_css": { "message": "unrestricted CSS" }, + "cap_lan": { + "message": "LAN" + }, "cap_other": { "message": "other" }, diff --git a/src/bg/RequestGuard.js b/src/bg/RequestGuard.js index 2b32a54..2fb824a 100644 --- a/src/bg/RequestGuard.js +++ b/src/bg/RequestGuard.js @@ -408,12 +408,31 @@ var RequestGuard = (() => { } }; const listeners = { - onBeforeRequest(request) { + async onBeforeRequest(request) { normalizeRequest(request); try { let redirected = initPendingRequest(request); let {policy} = ns - let {type} = request; + let {type, url, originUrl, tabId} = request; + + if (type === "xmlhttprequest" && + browser.runtime.onSyncMessage && + url.startsWith(browser.runtime.onSyncMessage.ENDPOINT_PREFIX)) { + return ALLOW; + } + let enforced = ns.isEnforced(tabId); + // check cross-zone WAN->LAN requests + if (enforced && originUrl && !Sites.isInternal(originUrl) && url.startsWith("http") && + !policy.can(originUrl, "lan", ns.policyContext(request)) && + (await iputil.isLocalURI(url)) && !(await iputil.isLocalURI(originUrl))) { + + debug("WAN->LAN request blocked", request); + let r = Object.assign({}, request); + r.url = originUrl; // we want to report the origin as needing the permission + Content.reportTo(r, false, "lan") + return ABORT; + } + if (type in policyTypesMap) { let previous = recent.find(request); if (previous) { @@ -424,19 +443,18 @@ var RequestGuard = (() => { recent.add(previous); let policyType = policyTypesMap[type]; - let {url, originUrl, documentUrl, tabId} = request; - - if (ns.unrestrictedTabs.has(tabId) && type.endsWith("frame") && url.startsWith("https:")) { - TabStatus.addOrigin(tabId, url); + let {documentUrl} = request; + if (!enforced) { + if (ns.unrestrictedTabs.has(tabId) && type.endsWith("frame") && url.startsWith("https:")) { + TabStatus.addOrigin(tabId, url); + } + return ALLOW; } - let isFetch = "fetch" === policyType; if ((isFetch || "frame" === policyType) && - (((isFetch && (!originUrl || - browser.runtime.onSyncMessage && - url.startsWith(browser.runtime.onSyncMessage.ENDPOINT_PREFIX) - ) || url === originUrl) && originUrl === documentUrl + (((isFetch && !originUrl + || url === originUrl) && originUrl === documentUrl // some extensions make them both undefined, // see https://github.com/eight04/image-picka/issues/150 ) || @@ -451,7 +469,7 @@ var RequestGuard = (() => { request.url = url = documentUrl || originUrl; } - let allowed = Sites.isInternal(url) || !ns.isEnforced(tabId); + let allowed = Sites.isInternal(url); if (!allowed) { if (tabId < 0 && documentUrl && documentUrl.startsWith("https:")) { allowed = [...ns.unrestrictedTabs] diff --git a/src/manifest.json b/src/manifest.json index 8592e5a..c25b62d 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -28,6 +28,7 @@ "webNavigation", "webRequest", "webRequestBlocking", + "dns", "" ], @@ -53,6 +54,9 @@ "/nscl/common/locale.js", "/nscl/common/Storage.js", "/nscl/common/include.js", + "/nscl/common/DNS.js", + "/nscl/common/AddressMatcherWithDNS.js", + "/nscl/common/iputil.js", "/nscl/service/DocStartInjection.js", "/nscl/service/LastListener.js", "/nscl/service/TabCache.js", diff --git a/src/nscl b/src/nscl index ea55fd9..7f2c372 160000 --- a/src/nscl +++ b/src/nscl @@ -1 +1 @@ -Subproject commit ea55fd9a837c5797099671386b0589159ad25328 +Subproject commit 7f2c37284c54c243afd6e4b7d9f3cb6952c149bd