[tor-commits] [tor-browser/tor-browser-45.2.0esr-6.5-1] Bug 16998: Isolate link rel=preconnect to first party

gk at torproject.org gk at torproject.org
Fri Jul 1 08:34:54 UTC 2016


commit be96c4f788ab616d94457bcc4dd1d098b156d62c
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Mon Jun 6 00:56:09 2016 -0700

    Bug 16998: Isolate link rel=preconnect to first party
---
 dom/base/nsDocument.cpp                 |  8 +++++--
 netwerk/base/nsIOService.cpp            | 41 +++++++++++++++++++++++++++++----
 netwerk/base/nsIOService.h              |  1 +
 netwerk/base/nsISpeculativeConnect.idl  | 11 ++++++++-
 netwerk/ipc/NeckoParent.cpp             |  7 +++---
 netwerk/ipc/NeckoParent.h               |  3 ++-
 netwerk/ipc/PNecko.ipdl                 |  2 +-
 netwerk/protocol/http/nsHttpHandler.cpp | 27 ++++++++++++++++++----
 netwerk/protocol/http/nsHttpHandler.h   |  1 +
 9 files changed, 84 insertions(+), 17 deletions(-)

diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 586e199..e7077a9 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -246,6 +246,8 @@
 
 #include "nsISpeculativeConnect.h"
 
+#include "ThirdPartyUtil.h"
+
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "mozilla/MediaManager.h"
 #endif // MOZ_MEDIA_NAVIGATOR
@@ -9733,10 +9735,12 @@ nsDocument::MaybePreconnect(nsIURI* aOrigURI, mozilla::CORSMode aCORSMode)
     return;
   }
 
+  nsCString firstPartyHost;
+  ThirdPartyUtil::GetFirstPartyHost(this, firstPartyHost);
   if (aCORSMode == CORS_ANONYMOUS) {
-    speculator->SpeculativeAnonymousConnect(uri, nullptr);
+    speculator->SpeculativeAnonymousConnectIsolated(uri, firstPartyHost, nullptr);
   } else {
-    speculator->SpeculativeConnect(uri, nullptr);
+    speculator->SpeculativeConnectIsolated(uri, firstPartyHost, nullptr);
   }
 }
 
diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp
index ad86c95..a864d0e 100644
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -51,6 +51,7 @@
 #include "ClosingService.h"
 #include "ReferrerPolicy.h"
 #include "nsContentSecurityManager.h"
+#include "ThirdPartyUtil.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsINetworkManager.h"
@@ -1822,10 +1823,14 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *cha
 
     nsLoadFlags loadFlags = 0;
     channel->GetLoadFlags(&loadFlags);
+
+    nsCString firstPartyHost;
+    ThirdPartyUtil::GetFirstPartyHost(channel, firstPartyHost);
+
     if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
-        speculativeHandler->SpeculativeAnonymousConnect(uri, mCallbacks);
+        speculativeHandler->SpeculativeAnonymousConnectIsolated(uri, firstPartyHost, mCallbacks);
     } else {
-        speculativeHandler->SpeculativeConnect(uri, mCallbacks);
+        speculativeHandler->SpeculativeConnectIsolated(uri, firstPartyHost, mCallbacks);
     }
 
     return NS_OK;
@@ -1833,6 +1838,7 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *cha
 
 nsresult
 nsIOService::SpeculativeConnectInternal(nsIURI *aURI,
+                                        const nsACString& aIsolationKey,
                                         nsIInterfaceRequestor *aCallbacks,
                                         bool aAnonymous)
 {
@@ -1867,6 +1873,17 @@ nsIOService::SpeculativeConnectInternal(nsIURI *aURI,
                             getter_AddRefs(channel));
     NS_ENSURE_SUCCESS(rv, rv);
 
+    // If we have an isolation key, use it as the document URI for this channel.
+    if (!aIsolationKey.IsEmpty()) {
+        nsCOMPtr<nsIHttpChannelInternal> channelInternal(do_QueryInterface(channel));
+        if (channelInternal) {
+            nsCString documentURISpec("https://");
+            documentURISpec.Append(aIsolationKey);
+            nsCOMPtr<nsIURI> documentURI;
+            /* nsresult rv = */ NS_NewURI(getter_AddRefs(documentURI), documentURISpec);
+            channelInternal->SetDocumentURI(documentURI);
+        }
+    }
     if (aAnonymous) {
         nsLoadFlags loadFlags = 0;
         channel->GetLoadFlags(&loadFlags);
@@ -1885,17 +1902,33 @@ nsIOService::SpeculativeConnectInternal(nsIURI *aURI,
 }
 
 NS_IMETHODIMP
+nsIOService::SpeculativeConnectIsolated(nsIURI *aURI,
+                                        const nsACString& aIsolationKey,
+                                        nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, false);
+}
+
+NS_IMETHODIMP
 nsIOService::SpeculativeConnect(nsIURI *aURI,
                                 nsIInterfaceRequestor *aCallbacks)
 {
-    return SpeculativeConnectInternal(aURI, aCallbacks, false);
+    return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, false);
+}
+
+NS_IMETHODIMP
+nsIOService::SpeculativeAnonymousConnectIsolated(nsIURI *aURI,
+                                                 const nsACString& aIsolationKey,
+                                                 nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, true);
 }
 
 NS_IMETHODIMP
 nsIOService::SpeculativeAnonymousConnect(nsIURI *aURI,
                                          nsIInterfaceRequestor *aCallbacks)
 {
-    return SpeculativeConnectInternal(aURI, aCallbacks, true);
+    return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, true);
 }
 
 void
diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h
index e948ffd..308cee7 100644
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -133,6 +133,7 @@ private:
                                                      nsIChannel** result);
 
     nsresult SpeculativeConnectInternal(nsIURI *aURI,
+                                        const nsACString& aIsolationKey,
                                         nsIInterfaceRequestor *aCallbacks,
                                         bool aAnonymous);
 
diff --git a/netwerk/base/nsISpeculativeConnect.idl b/netwerk/base/nsISpeculativeConnect.idl
index 15d63e1..eed9570 100644
--- a/netwerk/base/nsISpeculativeConnect.idl
+++ b/netwerk/base/nsISpeculativeConnect.idl
@@ -8,7 +8,7 @@
 interface nsIURI;
 interface nsIInterfaceRequestor;
 
-[scriptable, uuid(d74a17ac-5b8a-4824-a309-b1f04a3c4aed)]
+[scriptable, uuid(60cf321d-9f09-403a-b8b6-db221e6ca3a1)]
 interface nsISpeculativeConnect : nsISupports
 {
     /**
@@ -21,6 +21,7 @@ interface nsISpeculativeConnect : nsISupports
      * to actually open the new channel. 
      *
      * @param aURI the URI of the hinted transaction
+     * @param aIsolationKey the isolation key for the connection
      * @param aCallbacks any security callbacks for use with SSL for interfaces
      *        such as nsIBadCertListener. May be null.
      *
@@ -30,6 +31,14 @@ interface nsISpeculativeConnect : nsISupports
 
     void speculativeAnonymousConnect(in nsIURI aURI,
                                      in nsIInterfaceRequestor aCallbacks);
+
+    void speculativeConnectIsolated(in nsIURI aURI,
+                                    in AUTF8String aIsolationKey,
+                                    in nsIInterfaceRequestor aCallbacks);
+
+    void speculativeAnonymousConnectIsolated(in nsIURI aURI,
+                                             in AUTF8String aIsolationKey,
+                                             in nsIInterfaceRequestor aCallbacks);
 };
 
 /**
diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp
index 796e78f..fa4911b 100644
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -728,15 +728,16 @@ NeckoParent::DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* actor)
 }
 
 bool
-NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous)
+NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous,
+                                    const nsCString& aIsolationKey)
 {
   nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   if (uri && speculator) {
     if (aAnonymous) {
-      speculator->SpeculativeAnonymousConnect(uri, nullptr);
+      speculator->SpeculativeAnonymousConnectIsolated(uri, aIsolationKey, nullptr);
     } else {
-      speculator->SpeculativeConnect(uri, nullptr);
+      speculator->SpeculativeConnectIsolated(uri, aIsolationKey, nullptr);
     }
 
   }
diff --git a/netwerk/ipc/NeckoParent.h b/netwerk/ipc/NeckoParent.h
index 508ab6f..900328c 100644
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -167,7 +167,8 @@ protected:
                                           const uint32_t& flags,
                                           const nsCString& aNetworkInterface) override;
   virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) override;
-  virtual bool RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous) override;
+  virtual bool RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous,
+                                      const nsCString& aFirstPartyHost) override;
   virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
                                    const uint16_t& flags) override;
   virtual bool RecvCancelHTMLDNSPrefetch(const nsString& hostname,
diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl
index 2e1f2f5..0d0c7f8 100644
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -89,7 +89,7 @@ parent:
                   URIParams fileuri,
                   OptionalURIParams appuri);
 
-  SpeculativeConnect(URIParams uri, bool anonymous);
+  SpeculativeConnect(URIParams uri, bool anonymous, nsCString isolationKey);
   HTMLDNSPrefetch(nsString hostname, uint16_t flags);
   CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
 
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
index e425c22..97461fe 100644
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -2126,13 +2126,15 @@ nsHttpHandler::Observe(nsISupports *subject,
 
 nsresult
 nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI,
+                                          const nsACString& aIsolationKey,
                                           nsIInterfaceRequestor *aCallbacks,
                                           bool anonymous)
 {
+    nsCString isolationKey(aIsolationKey);
     if (IsNeckoChild()) {
         ipc::URIParams params;
         SerializeURI(aURI, params);
-        gNeckoChild->SendSpeculativeConnect(params, anonymous);
+        gNeckoChild->SendSpeculativeConnect(params, anonymous, isolationKey);
         return NS_OK;
     }
 
@@ -2205,26 +2207,41 @@ nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI,
     nsAutoCString username;
     aURI->GetUsername(username);
 
-    // TODO: Fix isolation for speculative connect.
     nsHttpConnectionInfo *ci =
-        new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, EmptyCString(), usingSSL);
+        new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, aIsolationKey, usingSSL);
     ci->SetAnonymous(anonymous);
 
     return SpeculativeConnect(ci, aCallbacks);
 }
 
 NS_IMETHODIMP
+nsHttpHandler::SpeculativeConnectIsolated(nsIURI *aURI,
+                                          const nsACString& aIsolationKey,
+                                          nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, false);
+}
+
+NS_IMETHODIMP
 nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
                                   nsIInterfaceRequestor *aCallbacks)
 {
-    return SpeculativeConnectInternal(aURI, aCallbacks, false);
+    return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, false);
+}
+
+NS_IMETHODIMP
+nsHttpHandler::SpeculativeAnonymousConnectIsolated(nsIURI *aURI,
+                                                   const nsACString& aIsolationKey,
+                                                   nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, true);
 }
 
 NS_IMETHODIMP
 nsHttpHandler::SpeculativeAnonymousConnect(nsIURI *aURI,
                                            nsIInterfaceRequestor *aCallbacks)
 {
-    return SpeculativeConnectInternal(aURI, aCallbacks, true);
+    return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, true);
 }
 
 void
diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h
index 1205dad..cf15775 100644
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -596,6 +596,7 @@ private:
 
 private:
     nsresult SpeculativeConnectInternal(nsIURI *aURI,
+                                        const nsACString& aIsolationKey,
                                         nsIInterfaceRequestor *aCallbacks,
                                         bool anonymous);
 };





More information about the tor-commits mailing list