[tbb-commits] [tor-browser/tor-browser-38.1.0esr-5.0-1] Bug #15502. Isolate blob, mediasource & mediastream URLs to first party

mikeperry at torproject.org mikeperry at torproject.org
Tue Jul 28 08:41:37 UTC 2015


commit f538052047ad61cf74f926381bc7c41b60fa2a3d
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Thu Jul 2 12:56:23 2015 -0700

    Bug #15502. Isolate blob, mediasource & mediastream URLs to first party
    
    This patch handles blob URLs created and retrieved in Web Workers.
    
    See also #15703 and #16429.
---
 dom/base/ThirdPartyUtil.cpp              |   21 ++++++
 dom/base/ThirdPartyUtil.h                |   12 +++
 dom/base/URL.cpp                         |   32 +++++---
 dom/base/moz.build                       |    1 +
 dom/base/nsDocument.cpp                  |   17 ++++-
 dom/base/nsHostObjectProtocolHandler.cpp |  120 ++++++++++++++++++------------
 dom/base/nsHostObjectProtocolHandler.h   |   15 ++--
 dom/fetch/Fetch.cpp                      |   17 ++++-
 dom/fetch/FetchDriver.cpp                |    8 +-
 dom/fetch/FetchDriver.h                  |    5 +-
 dom/html/HTMLMediaElement.cpp            |   17 ++++-
 dom/media/MediaResource.cpp              |    6 +-
 dom/workers/URL.cpp                      |   21 +++++-
 dom/workers/WorkerPrivate.cpp            |   22 +++++-
 14 files changed, 232 insertions(+), 82 deletions(-)

diff --git a/dom/base/ThirdPartyUtil.cpp b/dom/base/ThirdPartyUtil.cpp
index d0aed3a..e8ec06c 100644
--- a/dom/base/ThirdPartyUtil.cpp
+++ b/dom/base/ThirdPartyUtil.cpp
@@ -33,6 +33,27 @@ static PRLogModuleInfo *gThirdPartyLog;
 #undef LOG
 #define LOG(args)     PR_LOG(gThirdPartyLog, PR_LOG_DEBUG, args)
 
+// static
+mozIThirdPartyUtil* ThirdPartyUtil::gThirdPartyUtilService = nullptr;
+
+//static
+nsresult
+ThirdPartyUtil::GetFirstPartyHost(nsIChannel* aChannel, nsIDocument* aDocument, nsACString& aResult)
+{
+  if (!gThirdPartyUtilService) {
+    CallGetService(THIRDPARTYUTIL_CONTRACTID, &gThirdPartyUtilService);
+  }
+  nsCOMPtr<nsIURI> isolationURI;
+  nsresult rv = gThirdPartyUtilService->GetFirstPartyIsolationURI(aChannel, aDocument, getter_AddRefs(isolationURI));
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!isolationURI) {
+    // Isolation is not active.
+    aResult.Truncate();
+    return NS_OK;
+  }
+  return gThirdPartyUtilService->GetFirstPartyHostForIsolation(isolationURI, aResult);
+}
+
 nsresult
 ThirdPartyUtil::Init()
 {
diff --git a/dom/base/ThirdPartyUtil.h b/dom/base/ThirdPartyUtil.h
index c03740e..77e73f7 100644
--- a/dom/base/ThirdPartyUtil.h
+++ b/dom/base/ThirdPartyUtil.h
@@ -24,6 +24,18 @@ public:
 
   nsresult Init();
 
+  static mozIThirdPartyUtil* gThirdPartyUtilService;
+
+  static nsresult GetFirstPartyHost(nsIChannel* aChannel, nsIDocument* aDocument, nsACString& aResult);
+
+  static nsresult GetFirstPartyHost(nsIChannel* aChannel, nsACString& aResult) {
+    return GetFirstPartyHost(aChannel, nullptr, aResult);
+  }
+
+  static nsresult GetFirstPartyHost(nsIDocument* aDocument, nsACString& aResult) {
+    return GetFirstPartyHost(nullptr, aDocument, aResult);
+  }
+
 private:
   ~ThirdPartyUtil() {}
 
diff --git a/dom/base/URL.cpp b/dom/base/URL.cpp
index fea8dd2..1931c28 100644
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -17,6 +17,7 @@
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIURL.h"
+#include "ThirdPartyUtil.h"
 
 namespace mozilla {
 namespace dom {
@@ -152,12 +153,6 @@ URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
   nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
   nsCString url;
-  nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
-                                                          principal, url);
-  if (NS_FAILED(rv)) {
-    aError.Throw(rv);
-    return;
-  }
 
   nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.GetAsSupports());
   nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
@@ -172,6 +167,18 @@ URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
 
     nsIDocument* doc = window->GetExtantDoc();
     if (doc) {
+      nsCString isolationKey;
+      nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, isolationKey);
+      if (NS_FAILED(rv)) {
+        aError.Throw(rv);
+        return;
+      }
+      rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
+                                                              principal, isolationKey, url);
+      if (NS_FAILED(rv)) {
+        aError.Throw(rv);
+        return;
+      }
       doc->RegisterHostObjectUri(url);
     }
   }
@@ -193,10 +200,17 @@ URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL)
     nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.GetAsSupports());
     nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
 
-    if (window && window->GetExtantDoc()) {
-      window->GetExtantDoc()->UnregisterHostObjectUri(asciiurl);
+    if (window) {
+      nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
+      if (doc) {
+        doc->UnregisterHostObjectUri(asciiurl);
+        nsCString isolationKey;
+        nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, isolationKey);
+        if (NS_SUCCEEDED(rv)) {
+          nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl, isolationKey);
+        }
+      }
     }
-    nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
   }
 }
 
diff --git a/dom/base/moz.build b/dom/base/moz.build
index 27de87b..1d92f94 100644
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -194,6 +194,7 @@ EXPORTS.mozilla.dom += [
     'StyleSheetList.h',
     'SubtleCrypto.h',
     'Text.h',
+    'ThirdPartyUtil.h',
     'TreeWalker.h',
     'URL.h',
     'URLSearchParams.h',
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 47f611e..e5f0a2f2 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -226,6 +226,7 @@
 #include "nsLocation.h"
 #include "mozilla/dom/FontFaceSet.h"
 #include "mozilla/dom/BoxObject.h"
+#include "ThirdPartyUtil.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "mozilla/MediaManager.h"
@@ -1776,8 +1777,12 @@ nsDocument::~nsDocument()
 
   mPendingTitleChangeEvent.Revoke();
 
-  for (uint32_t i = 0; i < mHostObjectURIs.Length(); ++i) {
-    nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[i]);
+  nsCString isolationKey;
+  nsresult rv = ThirdPartyUtil::GetFirstPartyHost(this, isolationKey);
+  if (NS_SUCCEEDED(rv)) {
+    for (uint32_t i = 0; i < mHostObjectURIs.Length(); ++i) {
+      nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[i], isolationKey);
+    }
   }
 
   // We don't want to leave residual locks on images. Make sure we're in an
@@ -2156,8 +2161,12 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mCSSLoader)
   }
 
-  for (uint32_t i = 0; i < tmp->mHostObjectURIs.Length(); ++i) {
-    nsHostObjectProtocolHandler::RemoveDataEntry(tmp->mHostObjectURIs[i]);
+  nsCString isolationKey;
+  nsresult rv = ThirdPartyUtil::GetFirstPartyHost(tmp, isolationKey);
+  if (NS_SUCCEEDED(rv)) {
+    for (uint32_t i = 0; i < tmp->mHostObjectURIs.Length(); ++i) {
+      nsHostObjectProtocolHandler::RemoveDataEntry(tmp->mHostObjectURIs[i], isolationKey);
+    }
   }
 
   // We own only the items in mDOMMediaQueryLists that have listeners;
diff --git a/dom/base/nsHostObjectProtocolHandler.cpp b/dom/base/nsHostObjectProtocolHandler.cpp
index aac33f9..429938b 100644
--- a/dom/base/nsHostObjectProtocolHandler.cpp
+++ b/dom/base/nsHostObjectProtocolHandler.cpp
@@ -16,6 +16,7 @@
 #include "mozilla/dom/File.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LoadInfo.h"
+#include "ThirdPartyUtil.h"
 
 using mozilla::dom::FileImpl;
 using mozilla::ErrorResult;
@@ -29,6 +30,7 @@ struct DataInfo
   nsCOMPtr<nsISupports> mObject;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCString mStack;
+  nsCString mFirstPartyHost;
 };
 
 static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
@@ -298,6 +300,7 @@ nsresult
 nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
                                           nsISupports* aObject,
                                           nsIPrincipal* aPrincipal,
+                                          const nsACString& aIsolationKey,
                                           nsACString& aUri)
 {
   Init();
@@ -313,28 +316,55 @@ nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
 
   info->mObject = aObject;
   info->mPrincipal = aPrincipal;
+  // Record the first party host that originated this object.
+  info->mFirstPartyHost = aIsolationKey;
   mozilla::BlobURLsReporter::GetJSStackForBlob(info);
 
   gDataTable->Put(aUri, info);
   return NS_OK;
 }
 
+static DataInfo*
+GetDataInfo(const nsACString& aUri)
+{
+  if (!gDataTable) {
+    return nullptr;
+  }
+
+  DataInfo* res;
+  nsCString uriIgnoringRef;
+  int32_t hashPos = aUri.FindChar('#');
+  if (hashPos < 0) {
+    uriIgnoringRef = aUri;
+  }
+  else {
+    uriIgnoringRef = StringHead(aUri, hashPos);
+  }
+  gDataTable->Get(uriIgnoringRef, &res);
+
+  return res;
+}
+
 void
-nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri)
+nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri,
+                                             const nsACString& aIsolationKey)
 {
   if (gDataTable) {
-    nsCString uriIgnoringRef;
-    int32_t hashPos = aUri.FindChar('#');
-    if (hashPos < 0) {
-      uriIgnoringRef = aUri;
-    }
-    else {
-      uriIgnoringRef = StringHead(aUri, hashPos);
-    }
-    gDataTable->Remove(uriIgnoringRef);
-    if (gDataTable->Count() == 0) {
-      delete gDataTable;
-      gDataTable = nullptr;
+    DataInfo* info = GetDataInfo(aUri);
+    if (info->mFirstPartyHost == aIsolationKey) {
+      nsCString uriIgnoringRef;
+      int32_t hashPos = aUri.FindChar('#');
+      if (hashPos < 0) {
+        uriIgnoringRef = aUri;
+      }
+      else {
+        uriIgnoringRef = StringHead(aUri, hashPos);
+      }
+      gDataTable->Remove(uriIgnoringRef);
+      if (gDataTable->Count() == 0) {
+        delete gDataTable;
+        gDataTable = nullptr;
+      }
     }
   }
 }
@@ -375,27 +405,6 @@ nsHostObjectProtocolHandler::GenerateURIString(const nsACString &aScheme,
   return NS_OK;
 }
 
-static DataInfo*
-GetDataInfo(const nsACString& aUri)
-{
-  if (!gDataTable) {
-    return nullptr;
-  }
-
-  DataInfo* res;
-  nsCString uriIgnoringRef;
-  int32_t hashPos = aUri.FindChar('#');
-  if (hashPos < 0) {
-    uriIgnoringRef = aUri;
-  }
-  else {
-    uriIgnoringRef = StringHead(aUri, hashPos);
-  }
-  gDataTable->Get(uriIgnoringRef, &res);
-  
-  return res;
-}
-
 nsIPrincipal*
 nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
 {
@@ -431,13 +440,16 @@ nsHostObjectProtocolHandler::Traverse(const nsACString& aUri,
 }
 
 static nsISupports*
-GetDataObject(nsIURI* aURI)
+GetDataObject(nsIURI* aURI, const nsACString& aIsolationKey)
 {
   nsCString spec;
   aURI->GetSpec(spec);
 
   DataInfo* info = GetDataInfo(spec);
-  return info ? info->mObject : nullptr;
+  // Deny access to this object if the current first-party host
+  // doesn't match the originating first-party host.
+  return (info && info->mFirstPartyHost == aIsolationKey)
+         ? info->mObject : nullptr;
 }
 
 // -----------------------------------------------------------------------
@@ -493,9 +505,19 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
   nsCString spec;
   uri->GetSpec(spec);
 
-  DataInfo* info = GetDataInfo(spec);
+  nsCString firstPartyHost;
+  if (aLoadInfo) {
+    nsCOMPtr<nsIDOMDocument> loadingDOMDocument;
+    aLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDOMDocument));
+    nsCOMPtr<nsIDocument> loadingDocument = do_QueryInterface(loadingDOMDocument);
+    nsresult rv = ThirdPartyUtil::GetFirstPartyHost(loadingDocument, firstPartyHost);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
 
-  if (!info) {
+  DataInfo* info = GetDataInfo(spec);
+  // Deny access to this URI if the current first party host
+  // doesn't match the first party host when it was created.
+  if (!info || (info->mFirstPartyHost != firstPartyHost)) {
     return NS_ERROR_DOM_BAD_URI;
   }
 
@@ -594,13 +616,13 @@ nsFontTableProtocolHandler::GetScheme(nsACString &result)
 }
 
 nsresult
-NS_GetBlobForBlobURI(nsIURI* aURI, FileImpl** aBlob)
+NS_GetBlobForBlobURI(nsIURI* aURI, const nsACString& aIsolationKey, FileImpl** aBlob)
 {
   NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
 
   *aBlob = nullptr;
 
-  nsCOMPtr<FileImpl> blob = do_QueryInterface(GetDataObject(aURI));
+  nsCOMPtr<FileImpl> blob = do_QueryInterface(GetDataObject(aURI, aIsolationKey));
   if (!blob) {
     return NS_ERROR_DOM_BAD_URI;
   }
@@ -610,10 +632,12 @@ NS_GetBlobForBlobURI(nsIURI* aURI, FileImpl** aBlob)
 }
 
 nsresult
-NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
+NS_GetStreamForBlobURI(nsIURI* aURI,
+                       const nsACString& aIsolationKey,
+                       nsIInputStream** aStream)
 {
   nsRefPtr<FileImpl> blobImpl;
-  nsresult rv = NS_GetBlobForBlobURI(aURI, getter_AddRefs(blobImpl));
+  nsresult rv = NS_GetBlobForBlobURI(aURI, aIsolationKey, getter_AddRefs(blobImpl));
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -622,11 +646,13 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
 }
 
 nsresult
-NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream)
+NS_GetStreamForMediaStreamURI(nsIURI* aURI,
+                              const nsACString& aIsolationKey,
+                              mozilla::DOMMediaStream** aStream)
 {
   NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs");
 
-  nsISupports* dataObject = GetDataObject(aURI);
+  nsISupports* dataObject = GetDataObject(aURI, aIsolationKey);
   if (!dataObject) {
     return NS_ERROR_DOM_BAD_URI;
   }
@@ -669,13 +695,15 @@ nsFontTableProtocolHandler::NewURI(const nsACString& aSpec,
 }
 
 nsresult
-NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource)
+NS_GetSourceForMediaSourceURI(nsIURI* aURI,
+                              const nsACString& aIsolationKey,
+                              mozilla::dom::MediaSource** aSource)
 {
   NS_ASSERTION(IsMediaSourceURI(aURI), "Only call this with mediasource URIs");
 
   *aSource = nullptr;
 
-  nsCOMPtr<mozilla::dom::MediaSource> source = do_QueryInterface(GetDataObject(aURI));
+  nsCOMPtr<mozilla::dom::MediaSource> source = do_QueryInterface(GetDataObject(aURI, aIsolationKey));
   if (!source) {
     return NS_ERROR_DOM_BAD_URI;
   }
diff --git a/dom/base/nsHostObjectProtocolHandler.h b/dom/base/nsHostObjectProtocolHandler.h
index 977e5e0..e335886 100644
--- a/dom/base/nsHostObjectProtocolHandler.h
+++ b/dom/base/nsHostObjectProtocolHandler.h
@@ -53,8 +53,9 @@ public:
   static nsresult AddDataEntry(const nsACString& aScheme,
                                nsISupports* aObject,
                                nsIPrincipal* aPrincipal,
+                               const nsACString& aIsolationKey,
                                nsACString& aUri);
-  static void RemoveDataEntry(const nsACString& aUri);
+  static void RemoveDataEntry(const nsACString& aUri, const nsACString& aIsolationKey);
   static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
   static void Traverse(const nsACString& aUri, nsCycleCollectionTraversalCallback& aCallback);
 
@@ -121,16 +122,20 @@ inline bool IsFontTableURI(nsIURI* aUri)
 }
 
 extern nsresult
-NS_GetBlobForBlobURI(nsIURI* aURI, mozilla::dom::FileImpl** aBlob);
+NS_GetBlobForBlobURI(nsIURI* aURI, const nsACString& aIsolationKey,
+                     mozilla::dom::FileImpl** aBlob);
 
 extern nsresult
-NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
+NS_GetStreamForBlobURI(nsIURI* aURI, const nsACString& aIsolationKey,
+                       nsIInputStream** aStream);
 
 extern nsresult
-NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream);
+NS_GetStreamForMediaStreamURI(nsIURI* aURI, const nsACString& aIsolationKey,
+                              mozilla::DOMMediaStream** aStream);
 
 extern nsresult
-NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource);
+NS_GetSourceForMediaSourceURI(nsIURI* aURI, const nsACString& aIsolationKey,
+                              mozilla::dom::MediaSource** aSource);
 
 #define NS_BLOBPROTOCOLHANDLER_CID \
 { 0xb43964aa, 0xa078, 0x44b2, \
diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
index b84393e..9a53555 100644
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -27,6 +27,7 @@
 #include "mozilla/dom/Request.h"
 #include "mozilla/dom/Response.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/ThirdPartyUtil.h"
 #include "mozilla/dom/URLSearchParams.h"
 
 #include "InternalRequest.h"
@@ -174,13 +175,18 @@ public:
 
     nsCOMPtr<nsIPrincipal> principal = mResolver->GetWorkerPrivate()->GetPrincipal();
     nsCOMPtr<nsILoadGroup> loadGroup = mResolver->GetWorkerPrivate()->GetLoadGroup();
-    nsRefPtr<FetchDriver> fetch = new FetchDriver(mRequest, principal, loadGroup);
     nsIDocument* doc = mResolver->GetWorkerPrivate()->GetDocument();
+    nsCString isolationKey;
+    nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, isolationKey);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    nsRefPtr<FetchDriver> fetch = new FetchDriver(mRequest, principal, isolationKey, loadGroup);
     if (doc) {
       fetch->SetReferrerPolicy(doc->GetReferrerPolicy());
     }
 
-    nsresult rv = fetch->Fetch(mResolver);
+    rv = fetch->Fetch(mResolver);
     // Right now we only support async fetch, which should never directly fail.
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -230,10 +236,15 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
       return nullptr;
     }
 
+    nsCString isolationKey;
+    nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, isolationKey);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return nullptr;
+    }
     nsRefPtr<MainThreadFetchResolver> resolver = new MainThreadFetchResolver(p);
     nsCOMPtr<nsILoadGroup> loadGroup = doc->GetDocumentLoadGroup();
     nsRefPtr<FetchDriver> fetch =
-      new FetchDriver(r, doc->NodePrincipal(), loadGroup);
+      new FetchDriver(r, doc->NodePrincipal(), isolationKey, loadGroup);
     fetch->SetReferrerPolicy(doc->GetReferrerPolicy());
     aRv = fetch->Fetch(resolver);
     if (NS_WARN_IF(aRv.Failed())) {
diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
index ad54daf..b57141c 100644
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -28,6 +28,7 @@
 #include "Fetch.h"
 #include "InternalRequest.h"
 #include "InternalResponse.h"
+#include "mozilla/dom/ThirdPartyUtil.h"
 
 namespace mozilla {
 namespace dom {
@@ -36,9 +37,12 @@ NS_IMPL_ISUPPORTS(FetchDriver,
                   nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor,
                   nsIAsyncVerifyRedirectCallback)
 
-FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
+FetchDriver::FetchDriver(InternalRequest* aRequest,
+                         nsIPrincipal* aPrincipal,
+                         const nsACString& aIsolationKey,
                          nsILoadGroup* aLoadGroup)
   : mPrincipal(aPrincipal)
+  , mIsolationKey(aIsolationKey)
   , mLoadGroup(aLoadGroup)
   , mRequest(aRequest)
   , mFetchRecursionCount(0)
@@ -187,7 +191,7 @@ FetchDriver::BasicFetch()
 
   if (scheme.LowerCaseEqualsLiteral("blob")) {
     nsRefPtr<FileImpl> blobImpl;
-    rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl));
+    rv = NS_GetBlobForBlobURI(uri, mIsolationKey, getter_AddRefs(blobImpl));
     FileImpl* blob = static_cast<FileImpl*>(blobImpl.get());
     if (NS_WARN_IF(NS_FAILED(rv))) {
       FailWithNetworkError();
diff --git a/dom/fetch/FetchDriver.h b/dom/fetch/FetchDriver.h
index d58224209..c835149 100644
--- a/dom/fetch/FetchDriver.h
+++ b/dom/fetch/FetchDriver.h
@@ -53,7 +53,9 @@ public:
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
 
-  explicit FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
+  explicit FetchDriver(InternalRequest* aRequest,
+                       nsIPrincipal* aPrincipal,
+                       const nsACString& isolationKey,
                        nsILoadGroup* aLoadGroup);
   NS_IMETHOD Fetch(FetchDriverObserver* aObserver);
 
@@ -67,6 +69,7 @@ public:
 
 private:
   nsCOMPtr<nsIPrincipal> mPrincipal;
+  nsAutoCString mIsolationKey;
   nsCOMPtr<nsILoadGroup> mLoadGroup;
   nsRefPtr<InternalRequest> mRequest;
   nsRefPtr<InternalResponse> mResponse;
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 41a1505..d80cfff 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -90,6 +90,7 @@
 #include "ImageContainer.h"
 #include "nsRange.h"
 #include <algorithm>
+#include "ThirdPartyUtil.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gMediaElementLog;
@@ -521,7 +522,11 @@ HTMLMediaElement::GetMozMediaSourceObject() const
 {
   nsRefPtr<MediaSource> source;
   if (mLoadingSrc && IsMediaSourceURI(mLoadingSrc)) {
-    NS_GetSourceForMediaSourceURI(mLoadingSrc, getter_AddRefs(source));
+    nsCString isolationKey;
+    nsresult rv = ThirdPartyUtil::GetFirstPartyHost(GetOwnerDocument(), isolationKey);
+    if (NS_SUCCEEDED(rv)) {
+      NS_GetSourceForMediaSourceURI(mLoadingSrc, isolationKey, getter_AddRefs(source));
+    }
   }
   return source.forget();
 }
@@ -1191,7 +1196,10 @@ nsresult HTMLMediaElement::LoadResource()
 
   if (IsMediaStreamURI(mLoadingSrc)) {
     nsRefPtr<DOMMediaStream> stream;
-    rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream));
+    nsCString isolationKey;
+    rv = ThirdPartyUtil::GetFirstPartyHost(GetOwnerDocument(), isolationKey);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, isolationKey, getter_AddRefs(stream));
     if (NS_FAILED(rv)) {
       nsCString specUTF8;
       mLoadingSrc->GetSpec(specUTF8);
@@ -1206,7 +1214,10 @@ nsresult HTMLMediaElement::LoadResource()
 
   if (IsMediaSourceURI(mLoadingSrc)) {
     nsRefPtr<MediaSource> source;
-    rv = NS_GetSourceForMediaSourceURI(mLoadingSrc, getter_AddRefs(source));
+    nsCString isolationKey;
+    rv = ThirdPartyUtil::GetFirstPartyHost(GetOwnerDocument(), isolationKey);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = NS_GetSourceForMediaSourceURI(mLoadingSrc, isolationKey, getter_AddRefs(source));
     if (NS_FAILED(rv)) {
       nsCString specUTF8;
       mLoadingSrc->GetSpec(specUTF8);
diff --git a/dom/media/MediaResource.cpp b/dom/media/MediaResource.cpp
index 956776c..618b10a 100644
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -32,6 +32,7 @@
 #include <algorithm>
 #include "nsProxyRelease.h"
 #include "nsIContentPolicy.h"
+#include "mozilla/dom/ThirdPartyUtil.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMediaResourceLog;
@@ -1365,7 +1366,10 @@ nsresult FileMediaResource::Open(nsIStreamListener** aStreamListener)
 
       rv = NS_NewLocalFileInputStream(getter_AddRefs(mInput), file);
     } else if (IsBlobURI(mURI)) {
-      rv = NS_GetStreamForBlobURI(mURI, getter_AddRefs(mInput));
+      nsCString isolationKey;
+      rv = ThirdPartyUtil::GetFirstPartyHost(mChannel, isolationKey);
+      NS_ENSURE_SUCCESS(rv, rv);
+      rv = NS_GetStreamForBlobURI(mURI, isolationKey, getter_AddRefs(mInput));
     }
   } else {
     // Ensure that we never load a local file from some page on a
diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp
index fbf6987..1eda4fd 100644
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -24,6 +24,7 @@
 
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
+#include "ThirdPartyUtil.h"
 
 BEGIN_WORKERS_NAMESPACE
 using mozilla::dom::GlobalObject;
@@ -140,10 +141,17 @@ public:
       principal = mWorkerPrivate->GetPrincipal();
     }
 
+    nsCString firstPartyHost;
+    nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, firstPartyHost);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Isolation failed; blob URL creation denied.");
+      return false;
+    }
+
     nsCString url;
-    nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
+    rv = nsHostObjectProtocolHandler::AddDataEntry(
         NS_LITERAL_CSTRING(BLOBURI_SCHEME),
-        mBlobImpl, principal, url);
+        mBlobImpl, principal, firstPartyHost, url);
 
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to add data entry for the blob!");
@@ -209,8 +217,13 @@ public:
       if (doc) {
         doc->UnregisterHostObjectUri(url);
       }
-
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
+      nsCString isolationKey;
+      nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, isolationKey);
+      if (NS_FAILED(rv)) {
+        NS_WARNING("Isolation failed; blob removal denied.");
+        return false;
+      }
+      nsHostObjectProtocolHandler::RemoveDataEntry(url, isolationKey);
     }
 
     if (!window) {
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 0d4702d..d998471 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -99,6 +99,7 @@
 #include "WorkerRunnable.h"
 #include "WorkerScope.h"
 #include "WorkerThread.h"
+#include "ThirdPartyUtil.h"
 
 #ifdef XP_WIN
 #undef PostMessage
@@ -708,14 +709,17 @@ class MainThreadReleaseRunnable final : public nsRunnable
   nsTArray<nsCOMPtr<nsISupports>> mDoomed;
   nsTArray<nsCString> mHostObjectURIs;
   nsCOMPtr<nsILoadGroup> mLoadGroupToCancel;
+  nsRefPtr<WorkerPrivate> mWorkerPrivate;
 
 public:
   MainThreadReleaseRunnable(nsTArray<nsCOMPtr<nsISupports>>& aDoomed,
                             nsTArray<nsCString>& aHostObjectURIs,
+                            WorkerPrivate* aWorkerPrivate,
                             nsCOMPtr<nsILoadGroup>& aLoadGroupToCancel)
   {
     mDoomed.SwapElements(aDoomed);
     mHostObjectURIs.SwapElements(aHostObjectURIs);
+    mWorkerPrivate = aWorkerPrivate;
     mLoadGroupToCancel.swap(aLoadGroupToCancel);
   }
 
@@ -731,8 +735,17 @@ public:
 
     mDoomed.Clear();
 
-    for (uint32_t index = 0; index < mHostObjectURIs.Length(); index++) {
-      nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[index]);
+    nsCOMPtr<nsIDocument> doc;
+    nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
+    if (window) {
+      doc = window->GetExtantDoc();
+    }
+    nsCString isolationKey;
+    nsresult rv = ThirdPartyUtil::GetFirstPartyHost(doc, isolationKey);
+    if (NS_SUCCEEDED(rv)) {
+      for (uint32_t index = 0; index < mHostObjectURIs.Length(); index++) {
+        nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[index], isolationKey);
+      }
     }
 
     return NS_OK;
@@ -782,7 +795,8 @@ private:
     mFinishedWorker->StealHostObjectURIs(hostObjectURIs);
 
     nsRefPtr<MainThreadReleaseRunnable> runnable =
-      new MainThreadReleaseRunnable(doomed, hostObjectURIs, loadGroupToCancel);
+      new MainThreadReleaseRunnable(doomed, hostObjectURIs,
+                                    aWorkerPrivate, loadGroupToCancel);
     if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
       NS_WARNING("Failed to dispatch, going to leak!");
     }
@@ -840,7 +854,7 @@ private:
     mFinishedWorker->StealHostObjectURIs(hostObjectURIs);
 
     nsRefPtr<MainThreadReleaseRunnable> runnable =
-      new MainThreadReleaseRunnable(doomed, hostObjectURIs, loadGroupToCancel);
+      new MainThreadReleaseRunnable(doomed, hostObjectURIs, mFinishedWorker, loadGroupToCancel);
     if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
       NS_WARNING("Failed to dispatch, going to leak!");
     }





More information about the tbb-commits mailing list