Bug 1476570 - allow proxy to work on restricted domains, r?aswan draft
authorShane Caraveo <scaraveo@mozilla.com>
Thu, 02 Aug 2018 14:03:00 -0300
changeset 825914 4d92e1bbead80591cad03384ca6e8d65c26784fb
parent 824364 b21e782599f6af1bef5a7232190ac406a3234453
push id118205
push usermixedpuppy@gmail.com
push dateThu, 02 Aug 2018 17:14:33 +0000
reviewersaswan
bugs1476570
milestone63.0a1
Bug 1476570 - allow proxy to work on restricted domains, r?aswan Proxies must work with all requests, however the new onRequest proxy api has maching logic using ChannelWrapper which uses WebExtensionPolicy which checks against restricted domains. We need to bypass that check when matching for proxy requests. MozReview-Commit-ID: 5zCdmV1b9M7
toolkit/components/extensions/WebExtensionPolicy.h
toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
toolkit/components/extensions/webrequest/ChannelWrapper.cpp
--- a/toolkit/components/extensions/WebExtensionPolicy.h
+++ b/toolkit/components/extensions/WebExtensionPolicy.h
@@ -62,20 +62,20 @@ public:
   Result<nsString, nsresult> GetURL(const nsAString& aPath) const;
 
   void RegisterContentScript(WebExtensionContentScript& script,
                              ErrorResult& aRv);
 
   void UnregisterContentScript(const WebExtensionContentScript& script,
                                ErrorResult& aRv);
 
-  bool CanAccessURI(const URLInfo& aURI, bool aExplicit = false) const
+  bool CanAccessURI(const URLInfo& aURI, bool aExplicit = false, bool aCheckRestricted = true) const
   {
-    return (!IsRestrictedURI(aURI) &&
-            mHostPermissions && mHostPermissions->Matches(aURI, aExplicit));
+    return (!aCheckRestricted || !IsRestrictedURI(aURI)) &&
+            mHostPermissions && mHostPermissions->Matches(aURI, aExplicit);
   }
 
   bool IsPathWebAccessible(const nsAString& aPath) const
   {
     return mWebAccessiblePaths.Matches(aPath);
   }
 
   bool HasPermission(const nsAtom* aPermission) const
--- a/toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
+++ b/toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
@@ -3,20 +3,20 @@
 ChromeUtils.import("resource://gre/modules/Extension.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gProxyService",
                                    "@mozilla.org/network/protocol-proxy-service;1",
                                    "nsIProtocolProxyService");
 
 const TRANSPARENT_PROXY_RESOLVES_HOST = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST;
 
-function getProxyInfo() {
+function getProxyInfo(url = "http://www.mozilla.org/") {
   return new Promise((resolve, reject) => {
     let channel = NetUtil.newChannel({
-      uri: "http://www.mozilla.org/",
+      uri: url,
       loadUsingSystemPrincipal: true,
     });
 
     gProxyService.asyncResolve(channel, 0, {
       onProxyAvailable(req, uri, pi, status) {
         resolve(pi);
       },
     });
@@ -171,22 +171,23 @@ async function getExtension(expectedProx
   let extension = ExtensionTestUtils.loadExtension(extensionData);
   await extension.startup();
   await extension.awaitMessage("ready");
   return extension;
 }
 
 add_task(async function test_passthrough() {
   let ext1 = await getExtension(null);
-  let ext2 = await getExtension({host: "1.2.3.4", port: 8888, type: "http"});
+  let ext2 = await getExtension({host: "1.2.3.4", port: 8888, type: "https"});
 
-  let proxyInfo = await getProxyInfo();
+  // Also use a restricted url to test the ability to proxy those.
+  let proxyInfo = await getProxyInfo("https://addons.mozilla.org/");
 
   equal(proxyInfo.host, "1.2.3.4", `second extension won`);
   equal(proxyInfo.port, "8888", `second extension won`);
-  equal(proxyInfo.type, "http", `second extension won`);
+  equal(proxyInfo.type, "https", `second extension won`);
 
   await ext2.unload();
 
   proxyInfo = await getProxyInfo();
   equal(proxyInfo, null, `expected no proxy`);
   await ext1.unload();
 });
--- a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp
+++ b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp
@@ -516,23 +516,24 @@ ChannelWrapper::Matches(const dom::MozRe
   }
 
   auto& urlInfo = FinalURLInfo();
   if (aFilter.mUrls && !aFilter.mUrls->Matches(urlInfo)) {
     return false;
   }
 
   if (aExtension) {
-    if (!aExtension->CanAccessURI(urlInfo)) {
+    bool isProxy = aOptions.mIsProxy && aExtension->HasPermission(nsGkAtoms::proxy);
+    // Proxies are allowed access to all urls, including restricted urls.
+    if (!aExtension->CanAccessURI(urlInfo, false, !isProxy)) {
       return false;
     }
 
     // If this isn't the proxy phase of the request, check that the extension
     // has origin permissions for origin that originated the request.
-    bool isProxy = aOptions.mIsProxy && aExtension->HasPermission(nsGkAtoms::proxy);
     if (!isProxy) {
       if (IsSystemLoad()) {
         return false;
       }
 
       if (auto origin = DocumentURLInfo()) {
         nsAutoCString baseURL;
         aExtension->GetBaseURL(baseURL);