From 48053d96d44abbfa3c659e5fc817d998dda2bb35 Mon Sep 17 00:00:00 2001 From: hackademix Date: Mon, 10 Sep 2018 19:10:32 +0200 Subject: [PATCH] Better IPV6 support. --- src/bg/ChildPolicies.js | 25 ++++++++++++++++--------- src/common/Policy.js | 2 +- src/content/content.js | 8 +------- src/content/staticNS.js | 21 ++++++++++++++++++++- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/bg/ChildPolicies.js b/src/bg/ChildPolicies.js index 7f94ce0..7df3253 100644 --- a/src/bg/ChildPolicies.js +++ b/src/bg/ChildPolicies.js @@ -56,7 +56,7 @@ let protocolRx = /^(\w+):/i; let pathRx = /(?:[^:/]\/|:\/{3})$/; let portRx = /:\d+(?=\/|$)/; - let validMatchPatternRx = /^(?:\*|(?:http|ws|ftp)s?|file):\/\/(?:\*|(?:\*\.)?[\w\u0100-\uf000][\w\u0100-\uf000.-]*)?\/(\*|[^*]*)$/; + let validMatchPatternRx = /^(?:\*|(?:http|ws|ftp)s?|file):\/\/(?:\*|(?:\*\.)?[\w\u0100-\uf000][\w\u0100-\uf000.-]*|\[[\w:]+\])?\/(\*|[^*]*)$/; let validMatchPattern = mp => validMatchPatternRx.test(mp); @@ -67,23 +67,30 @@ mp = Sites.cleanUrl(mp); if (!mp) return false; } else { - let protocol = Sites.isSecureDomainKey(site) ? "https://" : "*://"; - mp = `${protocol}*`; + mp = Sites.isSecureDomainKey(site) ? "https://" : "*://"; let hostname = Sites.toggleSecureDomainKey(site, false).replace(portRx, ''); if (hostname && hostname !== ".") { - if (!tld.preserveFQDNs) hostname = tld.normalize(hostname); - mp += hostname.startsWith(".") ? hostname : `.${hostname}`; + if (tld.isIp(hostname) || hostname.includes("*")) { + mp += hostname; + } else { + if (!tld.preserveFQDNs) hostname = tld.normalize(hostname); + mp += hostname.startsWith(".") ? `*${hostname}` : `*.${hostname}`; + } + } else { + mp += "*"; } if (!(hostname && hostname.includes("/"))) mp += "/"; } - return validMatchPatternRx.test(mp) && ( - mp.endsWith("/") ? `${mp}*` : [mp, `${mp}?*`, `${mp}#*`]); + return validMatchPattern(mp) && + (mp.endsWith("/") ? `${mp}*` : [mp, `${mp}?*`, `${mp}#*`]); }; let withFQDNs = patterns => { - return tld.preserveFQDNs ? patterns : patterns.concat( - patterns.map(p => p.replace(/^(?:\w+|\*):\/\/[^/]*[^.*/]/, '$&.') + if (tld.preserveFQDNs) return patterns; + let rx = /^(?:\w+|\*):\/\/([^/]*[^.*/])/; + return patterns.concat( + patterns.map(p => p.replace(rx, (m, host) => tld.isIp(host) ? m : m + ".") ).filter(validMatchPattern) ); } diff --git a/src/common/Policy.js b/src/common/Policy.js index 37bd164..55e9ad1 100644 --- a/src/common/Policy.js +++ b/src/common/Policy.js @@ -11,7 +11,7 @@ var {Permissions, Policy, Sites} = (() => { class Sites extends Map { static secureDomainKey(domain) { - return domain.includes(":") ? domain : `${SECURE_DOMAIN_PREFIX}${domain}`; + return /^[ยง\w]+:/.test(domain) ? domain : `${SECURE_DOMAIN_PREFIX}${domain}`; } static isSecureDomainKey(domain) { return domain.startsWith(SECURE_DOMAIN_PREFIX); diff --git a/src/content/content.js b/src/content/content.js index fc76906..dc493c2 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -49,15 +49,9 @@ var notifyPage = async () => { if (document.readyState === "complete") { try { if (!("canScript" in ns)) { - let childPolicy = await Messages.send("fetchChildPolicy", {url: document.URL}); - if (!childPolicy) { - debug(`No answer to fetchChildPolicy message. This should not be happening.`); - return; - } - ns.setup(childPolicy.permissions, childPolicy.MARKER); + ns.fetchPolicy(); return; } - await Messages.send("pageshow", {seen: seen.list, canScript: ns.canScript}); return true; } catch (e) { diff --git a/src/content/staticNS.js b/src/content/staticNS.js index 6179da0..4e192b8 100644 --- a/src/content/staticNS.js +++ b/src/content/staticNS.js @@ -33,7 +33,17 @@ backlog.add(eventName); }, - setup(permissions, MARKER) { + async fetchPolicy() { + let policy = await Messages.send("fetchChildPolicy", {url: document.URL}); + if (!policy) { + debug(`No answer to fetchChildPolicy message. This should not be happening.`); + return false; + } + this.setup(policy.permissions, policy.MARKER, true); + return true; + }, + + setup(permissions, MARKER, fetched = false) { this.config.permissions = permissions; // ugly hack: since now we use registerContentScript instead of the @@ -75,6 +85,15 @@ this.capabilities = Object.assign( new Set(["script"]), { has() { return true; } }); } else { + if (!fetched) { + let hostname = window.location.hostname; + if (hostname && hostname.startsWith("[")) { + // WebExt match patterns don't seem to support IPV6 (Firefox 63)... + debug("Ignoring child policy setup parameters for IPV6 address %s, forcing IPC...", hostname); + this.fetchPolicy(); + return; + } + } let perms = this.config.permissions; this.capabilities = new Set(perms.capabilities); new DocumentCSP(document).apply(this.capabilities, this.embeddingDocument);