[tbb-commits] [tor-browser/tor-browser-31.6.0esr-4.5-1] Bug #15502. Isolate blob URLs to first party; no blobURLs in Web Workers

mikeperry at torproject.org mikeperry at torproject.org
Wed Apr 22 02:44:21 UTC 2015


commit 0d67ab406bdd3cf095802cb25c081641aa1f0bcc
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Sun Apr 12 13:47:55 2015 -0700

    Bug #15502. Isolate blob URLs to first party; no blobURLs in Web Workers
---
 content/base/src/ThirdPartyUtil.cpp              |    9 +++++++++
 content/base/src/nsHostObjectProtocolHandler.cpp |   23 ++++++++++++++++++++--
 dom/workers/URL.cpp                              |    7 +++++++
 netwerk/base/public/mozIThirdPartyUtil.idl       |   15 ++++++++++++++
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp
index 695392f..0e037d1 100644
--- a/content/base/src/ThirdPartyUtil.cpp
+++ b/content/base/src/ThirdPartyUtil.cpp
@@ -635,3 +635,12 @@ ThirdPartyUtil::GetFirstPartyHostForIsolation(nsIURI *aFirstPartyURI,
   aHost.Append("--");
   return NS_OK;
 }
+
+NS_IMETHODIMP
+ThirdPartyUtil::GetFirstPartyHostFromCaller(nsACString& aHost) {
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = GetFirstPartyIsolationURI(nullptr,
+                 nsContentUtils::GetDocumentFromCaller(), getter_AddRefs(uri));
+  NS_ENSURE_SUCCESS(rv, rv);
+  return GetFirstPartyHostForIsolation(uri, aHost);
+}
diff --git a/content/base/src/nsHostObjectProtocolHandler.cpp b/content/base/src/nsHostObjectProtocolHandler.cpp
index 10ec44c..e578804 100644
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -15,6 +15,7 @@
 #include "mozilla/dom/MediaSource.h"
 #include "nsIMemoryReporter.h"
 #include "mozilla/Preferences.h"
+#include "mozIThirdPartyUtil.h"
 
 // -----------------------------------------------------------------------
 // Hash table
@@ -24,9 +25,20 @@ struct DataInfo
   nsCOMPtr<nsISupports> mObject;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCString mStack;
+  nsCString mFirstPartyHost;
 };
 
 static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
+static nsCOMPtr<mozIThirdPartyUtil> gThirdPartyUtilService;
+
+static nsCString GetFirstPartyHostFromCaller() {
+  if (!gThirdPartyUtilService) {
+    gThirdPartyUtilService = do_GetService(THIRDPARTYUTIL_CONTRACTID);
+  }
+  nsCString host;
+  gThirdPartyUtilService->GetFirstPartyHostFromCaller(host);
+  return host;
+}
 
 // Memory reporting for the hash table.
 namespace mozilla {
@@ -290,6 +302,8 @@ nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
 
   info->mObject = aObject;
   info->mPrincipal = aPrincipal;
+  // Record the first party host that originated this object.
+  info->mFirstPartyHost = GetFirstPartyHostFromCaller();
   mozilla::BlobURLsReporter::GetJSStackForBlob(info);
 
   gDataTable->Put(aUri, info);
@@ -401,7 +415,10 @@ GetDataObject(nsIURI* aURI)
   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 == GetFirstPartyHostFromCaller())
+         ? info->mObject : nullptr;
 }
 
 // -----------------------------------------------------------------------
@@ -457,7 +474,9 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
 
   DataInfo* info = GetDataInfo(spec);
 
-  if (!info) {
+  // 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 != GetFirstPartyHostFromCaller())) {
     return NS_ERROR_DOM_BAD_URI;
   }
   nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(info->mObject);
diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp
index f80594e..d52e4c6 100644
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -894,6 +894,13 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob,
   JSContext* cx = aGlobal.GetContext();
   WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
 
+  if (!workerPrivate->IsChromeWorker()) {
+    workerPrivate->ReportError(cx, "Worker attempted to use createObjectURL; denied.", nullptr);
+    NS_NAMED_LITERAL_STRING(argStr, "URL.createObjectURL");
+    aRv.ThrowTypeError(MSG_METHOD_THIS_UNWRAPPING_DENIED, &argStr);
+    return;
+  }
+
   nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob);
   if (!blob) {
     SetDOMStringToNull(aResult);
diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl
index 0bb632b..0b0f410 100644
--- a/netwerk/base/public/mozIThirdPartyUtil.idl
+++ b/netwerk/base/public/mozIThirdPartyUtil.idl
@@ -246,6 +246,21 @@ interface mozIThirdPartyUtil : nsISupports
    *         for which we generate a pseudo host.
    */
   AUTF8String getFirstPartyHostForIsolation(in nsIURI aFirstPartyURI);
+
+  /**
+   * getFirstPartyHostFromCaller
+   *
+   * Obtain the host or pseudo-host for the first party URI belonging
+   * to the calling document. See getFirstPartyHostForIsolation(...) for
+   * examples.
+   *
+   * @return host or pseudo host.
+   *
+   * @throws if the calling document's first party URI lacks a host
+   *         and the scheme is not a whitelisted one for which we
+   *         generate a pseudo host.
+   */
+  AUTF8String getFirstPartyHostFromCaller();
 };
 
 %{ C++





More information about the tbb-commits mailing list