Bug 1228139 - Remove nsIURIWithPrincipal - part 3 - main part, r=bz
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 24 Jul 2018 22:15:57 +0200
changeset 485900 09917998d963a298ad6214fcc512e73b66259199
parent 485899 3549739dde68499b4224e7b0fcc4cef6bc228755
child 485901 fef4321d9525fa0ba17dedc3085b246f9596e77b
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1228139
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1228139 - Remove nsIURIWithPrincipal - part 3 - main part, r=bz nsIURIWithPrincipal is currently used to retrieve the nsIPrincipal from a BlobURL object. BlobURLProtocolHandler has a hashtable containing, for each blobURL, a BlobImpl and its nsIPrincipal. This patch introduces BlobURLProtocolHandler::GetBlobURLPrincipal() that retrieves the nsIPrincipal from this hashtable. This patch fixes also a bug in how the revocation of blobURLs is broadcasted to other processes. This should be done immediately because each process creates its own timer to revoke them after 5 seconds. An important change is related to NS_SecurityCompareURIs() where, if 1 (or both) of the 2 URIs to compare, is a revoked BlobURL, we will QI its URL to nsIStandardURL and fail out at that point.
caps/BasePrincipal.cpp
caps/ContentPrincipal.cpp
caps/NullPrincipal.cpp
caps/OriginAttributes.cpp
dom/file/uri/BlobURL.cpp
dom/file/uri/BlobURL.h
dom/file/uri/BlobURLChannel.cpp
dom/file/uri/BlobURLProtocolHandler.cpp
dom/file/uri/BlobURLProtocolHandler.h
ipc/glue/URIParams.ipdlh
netwerk/base/moz.build
netwerk/base/nsIURIWithPrincipal.idl
netwerk/base/nsNetUtil.cpp
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -9,22 +9,22 @@
 #include "nsDocShell.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIStandardURL.h"
 
 #include "ExpandedPrincipal.h"
 #include "nsNetUtil.h"
-#include "nsIURIWithPrincipal.h"
 #include "nsScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/ContentPrincipal.h"
 #include "mozilla/NullPrincipal.h"
+#include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/CSPDictionariesBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 
 namespace mozilla {
 
 BasePrincipal::BasePrincipal(PrincipalKind aKind)
   : mKind(aKind)
@@ -406,25 +406,22 @@ BasePrincipal::CreateCodebasePrincipal(n
   bool inheritsPrincipal;
   nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                                     &inheritsPrincipal);
   if (NS_FAILED(rv) || inheritsPrincipal) {
     return NullPrincipal::Create(aAttrs);
   }
 
   // Check whether the URI knows what its principal is supposed to be.
-  nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
-  if (uriPrinc) {
-    nsCOMPtr<nsIPrincipal> principal;
-    uriPrinc->GetPrincipal(getter_AddRefs(principal));
-    if (!principal) {
-      return NullPrincipal::Create(aAttrs);
-    }
-    RefPtr<BasePrincipal> concrete = Cast(principal);
-    return concrete.forget();
+  nsCOMPtr<nsIPrincipal> blobPrincipal;
+  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
+                                                       getter_AddRefs(blobPrincipal))) {
+    MOZ_ASSERT(blobPrincipal);
+    RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
+    return principal.forget();
   }
 
   // Mint a codebase principal.
   RefPtr<ContentPrincipal> codebase = new ContentPrincipal();
   rv = codebase->Init(aURI, aAttrs, aOriginNoSuffix);
   NS_ENSURE_SUCCESS(rv, nullptr);
   return codebase.forget();
 }
@@ -434,17 +431,17 @@ BasePrincipal::CreateCodebasePrincipal(c
 {
   MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
              "CreateCodebasePrincipal does not support System and Expanded principals");
 
   MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
              "CreateCodebasePrincipal does not support NullPrincipal");
 
   nsAutoCString originNoSuffix;
-  mozilla::OriginAttributes attrs;
+  OriginAttributes attrs;
   if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
     return nullptr;
   }
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
   NS_ENSURE_SUCCESS(rv, nullptr);
 
--- a/caps/ContentPrincipal.cpp
+++ b/caps/ContentPrincipal.cpp
@@ -2,41 +2,41 @@
 /* vim: set ts=2 sw=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ContentPrincipal.h"
 
 #include "mozIThirdPartyUtil.h"
+#include "nsContentUtils.h"
 #include "nscore.h"
 #include "nsScriptSecurityManager.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "pratom.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIStandardURL.h"
-#include "nsIURIWithPrincipal.h"
 #include "nsJSPrincipals.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIProtocolHandler.h"
 #include "nsError.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsNetCID.h"
 #include "js/Wrapper.h"
 
+#include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ExtensionPolicyService.h"
-#include "mozilla/NullPrincipal.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/HashFunctions.h"
 
 using namespace mozilla;
 
 static inline ExtensionPolicyService&
 EPS()
 {
@@ -160,30 +160,21 @@ ContentPrincipal::GenerateOriginNoSuffix
       aOriginNoSuffix.Truncate();
       return NS_ERROR_FAILURE;
     }
     return NS_OK;
   }
 
   // This URL can be a blobURL. In this case, we should use the 'parent'
   // principal instead.
-  nsCOMPtr<nsIURIWithPrincipal> uriWithPrincipal = do_QueryInterface(origin);
-  if (uriWithPrincipal) {
-    nsCOMPtr<nsIPrincipal> uriPrincipal;
-    rv = uriWithPrincipal->GetPrincipal(getter_AddRefs(uriPrincipal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // If there is not a principal for this blobURL, it means that the blobURL
-    // has been revoked. Let's use a nullPrincipal instead.
-    if (!uriPrincipal) {
-      uriPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
-      MOZ_ASSERT(uriPrincipal);
-    }
-
-    return uriPrincipal->GetOriginNoSuffix(aOriginNoSuffix);
+  nsCOMPtr<nsIPrincipal> blobPrincipal;
+  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(origin,
+                                                       getter_AddRefs(blobPrincipal))) {
+    MOZ_ASSERT(blobPrincipal);
+    return blobPrincipal->GetOriginNoSuffix(aOriginNoSuffix);
   }
 
   // If we reached this branch, we can only create an origin if we have a
   // nsIStandardURL.  So, we query to a nsIStandardURL, and fail if we aren't
   // an instance of an nsIStandardURL nsIStandardURLs have the good property
   // of escaping the '^' character in their specs, which means that we can be
   // sure that the caret character (which is reserved for delimiting the end
   // of the spec, and the beginning of the origin attributes) is not present
@@ -272,28 +263,23 @@ ContentPrincipal::GetURI(nsIURI** aURI)
 {
   NS_ADDREF(*aURI = mCodebase);
   return NS_OK;
 }
 
 bool
 ContentPrincipal::MayLoadInternal(nsIURI* aURI)
 {
-  // See if aURI is something like a Blob URI that is actually associated with
-  // a principal.
-  nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
-  if (uriWithPrin) {
-    nsCOMPtr<nsIPrincipal> uriPrin;
-    nsresult rv = uriWithPrin->GetPrincipal(getter_AddRefs(uriPrin));
-    if (NS_WARN_IF(NS_FAILED(rv)) || !uriPrin) {
-      // BlobURL has been revoked.
-      return false;
-    }
+  MOZ_ASSERT(aURI);
 
-    return nsIPrincipal::Subsumes(uriPrin);
+  nsCOMPtr<nsIPrincipal> blobPrincipal;
+  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
+                                                       getter_AddRefs(blobPrincipal))) {
+    MOZ_ASSERT(blobPrincipal);
+    return nsIPrincipal::Subsumes(blobPrincipal);
   }
 
   // If this principal is associated with an addon, check whether that addon
   // has been given permission to load from this domain.
   if (AddonAllowsLoad(aURI)) {
     return true;
   }
 
--- a/caps/NullPrincipal.cpp
+++ b/caps/NullPrincipal.cpp
@@ -11,17 +11,16 @@
  */
 
 #include "mozilla/ArrayUtils.h"
 
 #include "nsDocShell.h"
 #include "NullPrincipal.h"
 #include "NullPrincipalURI.h"
 #include "nsMemory.h"
-#include "nsIURIWithPrincipal.h"
 #include "nsIClassInfoImpl.h"
 #include "nsNetCID.h"
 #include "nsError.h"
 #include "nsIScriptSecurityManager.h"
 #include "ContentPrincipal.h"
 #include "nsScriptSecurityManager.h"
 #include "pratom.h"
 
@@ -180,24 +179,20 @@ NullPrincipal::SetDomain(nsIURI* aDomain
   // seems counterproductive.
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 bool
 NullPrincipal::MayLoadInternal(nsIURI* aURI)
 {
   // Also allow the load if we are the principal of the URI being checked.
-  nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
-  if (uriPrinc) {
-    nsCOMPtr<nsIPrincipal> principal;
-    uriPrinc->GetPrincipal(getter_AddRefs(principal));
-
-    if (principal == this) {
-      return true;
-    }
+  nsCOMPtr<nsIPrincipal> blobPrincipal;
+  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
+                                                       getter_AddRefs(blobPrincipal))) {
+    return blobPrincipal == this;
   }
 
   return false;
 }
 
 NS_IMETHODIMP
 NullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
--- a/caps/OriginAttributes.cpp
+++ b/caps/OriginAttributes.cpp
@@ -1,21 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/OriginAttributes.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/URLSearchParams.h"
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIURI.h"
-#include "nsIURIWithPrincipal.h"
 #include "nsURLHelper.h"
 
 namespace mozilla {
 
 using dom::URLParams;
 
 bool OriginAttributes::sFirstPartyIsolation = false;
 bool OriginAttributes::sRestrictedOpenerAccess = false;
@@ -81,28 +81,25 @@ OriginAttributes::SetFirstPartyDomain(co
     return;
   }
 
   nsAutoCString scheme;
   rv = aURI->GetScheme(scheme);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (scheme.EqualsLiteral("about")) {
     mFirstPartyDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
-  } else if (scheme.EqualsLiteral("blob")) {
-    nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
-    if (uriPrinc) {
-      nsCOMPtr<nsIPrincipal> principal;
-      rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
-      NS_ENSURE_SUCCESS_VOID(rv);
+    return;
+  }
 
-      // a revoked blobURL doesn't expose a principal.
-      if (principal) {
-        mFirstPartyDomain = principal->OriginAttributesRef().mFirstPartyDomain;
-      }
-    }
+  nsCOMPtr<nsIPrincipal> blobPrincipal;
+  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
+                                                       getter_AddRefs(blobPrincipal))) {
+    MOZ_ASSERT(blobPrincipal);
+    mFirstPartyDomain = blobPrincipal->OriginAttributesRef().mFirstPartyDomain;
+    return;
   }
 }
 
 void
 OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
                                       const nsACString& aDomain)
 {
   bool isFirstPartyEnabled = IsFirstPartyEnabled();
--- a/dom/file/uri/BlobURL.cpp
+++ b/dom/file/uri/BlobURL.cpp
@@ -18,114 +18,78 @@ static NS_DEFINE_CID(kHOSTOBJECTURICID, 
 
 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
 
 NS_IMPL_ADDREF_INHERITED(BlobURL, mozilla::net::nsSimpleURI)
 NS_IMPL_RELEASE_INHERITED(BlobURL, mozilla::net::nsSimpleURI)
 
 NS_INTERFACE_MAP_BEGIN(BlobURL)
-  NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
   if (aIID.Equals(kHOSTOBJECTURICID))
     foundInterface = static_cast<nsIURI*>(this);
   else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
     // Need to return explicitly here, because if we just set foundInterface
     // to null the NS_INTERFACE_MAP_END_INHERITING will end up calling into
     // nsSimplURI::QueryInterface and finding something for this CID.
     *aInstancePtr = nullptr;
     return NS_NOINTERFACE;
   }
   else
 NS_INTERFACE_MAP_END_INHERITING(mozilla::net::nsSimpleURI)
 
-// nsIURIWithPrincipal methods:
-
-NS_IMETHODIMP
-BlobURL::GetPrincipal(nsIPrincipal** aPrincipal)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIPrincipal> principal = mPrincipal.get();
-  principal.forget(aPrincipal);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BlobURL::GetPrincipalUri(nsIURI** aUri)
-{
-  if (mPrincipal) {
-    mPrincipal->GetURI(aUri);
-  }
-  else {
-    *aUri = nullptr;
-  }
-
-  return NS_OK;
-}
+BlobURL::BlobURL()
+  : mRevoked(false)
+{}
 
 // nsISerializable methods:
 
 NS_IMETHODIMP
 BlobURL::Read(nsIObjectInputStream* aStream)
 {
   MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 BlobURL::ReadPrivate(nsIObjectInputStream *aStream)
 {
   nsresult rv = mozilla::net::nsSimpleURI::ReadPrivate(aStream);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsISupports> supports;
-  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
+  rv = aStream->ReadBoolean(&mRevoked);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(supports, &rv);
-  mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", principal, false);
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 BlobURL::Write(nsIObjectOutputStream* aStream)
 {
   nsresult rv = mozilla::net::nsSimpleURI::Write(aStream);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIPrincipal> principal = mPrincipal.get();
-  return NS_WriteOptionalCompoundObject(aStream, principal,
-                                        NS_GET_IID(nsIPrincipal),
-                                        true);
+  rv = aStream->WriteBoolean(mRevoked);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
 }
 
 // nsIIPCSerializableURI methods:
 void
 BlobURL::Serialize(mozilla::ipc::URIParams& aParams)
 {
   using namespace mozilla::ipc;
 
   HostObjectURIParams hostParams;
   URIParams simpleParams;
 
   mozilla::net::nsSimpleURI::Serialize(simpleParams);
   hostParams.simpleParams() = simpleParams;
 
-  nsCOMPtr<nsIPrincipal> principal = mPrincipal.get();
-  if (principal) {
-    PrincipalInfo info;
-    nsresult rv = PrincipalToPrincipalInfo(principal, &info);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-
-    hostParams.principal() = info;
-  } else {
-    hostParams.principal() = mozilla::void_t();
-  }
+  hostParams.revoked() = mRevoked;
 
   aParams = hostParams;
 }
 
 bool
 BlobURL::Deserialize(const mozilla::ipc::URIParams& aParams)
 {
   using namespace mozilla::ipc;
@@ -136,35 +100,25 @@ BlobURL::Deserialize(const mozilla::ipc:
   }
 
   const HostObjectURIParams& hostParams = aParams.get_HostObjectURIParams();
 
   if (!mozilla::net::nsSimpleURI::Deserialize(hostParams.simpleParams())) {
     return false;
   }
 
-  if (hostParams.principal().type() == OptionalPrincipalInfo::Tvoid_t) {
-    return true;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(hostParams.principal().get_PrincipalInfo());
-  if (!principal) {
-    return false;
-  }
-  mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", principal, false);
-
+  mRevoked = hostParams.revoked();
   return true;
 }
 
 nsresult
 BlobURL::SetScheme(const nsACString& aScheme)
 {
   // Disallow setting the scheme, since that could cause us to be associated
-  // with a different protocol handler that doesn't expect us to be carrying
-  // around a principal with nsIURIWithPrincipal.
+  // with a different protocol handler.
   return NS_ERROR_FAILURE;
 }
 
 // nsIURI methods:
 nsresult
 BlobURL::CloneInternal(mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
                        const nsACString& newRef,
                        nsIURI** aClone)
@@ -176,18 +130,17 @@ BlobURL::CloneInternal(mozilla::net::nsS
 
 #ifdef DEBUG
   RefPtr<BlobURL> uriCheck;
   rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
   MOZ_ASSERT(NS_SUCCEEDED(rv) && uriCheck);
 #endif
 
   BlobURL* u = static_cast<BlobURL*>(simpleClone.get());
-
-  u->mPrincipal = mPrincipal;
+  u->mRevoked = mRevoked;
 
   simpleClone.forget(aClone);
   return NS_OK;
 }
 
 /* virtual */ nsresult
 BlobURL::EqualsInternal(nsIURI* aOther,
                         mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
@@ -204,33 +157,24 @@ BlobURL::EqualsInternal(nsIURI* aOther,
     *aResult = false;
     return NS_OK;
   }
 
   // Compare the member data that our base class knows about.
   *aResult = mozilla::net::nsSimpleURI::EqualsInternal(otherUri,
                                                        aRefHandlingMode);
 
-#ifdef DEBUG
-  // mPrincipal can be null if the blobURL has been revoked.
-  if (*aResult && mPrincipal && otherUri->mPrincipal) {
-    bool equal = false;
-    nsresult rv = mPrincipal->Equals(otherUri->mPrincipal, &equal);
-    MOZ_ASSERT(NS_SUCCEEDED(rv) && equal);
-  }
-#endif
-
+  // We don't want to compare the revoked flag.
   return NS_OK;
 }
 
 // Queries this list of interfaces. If none match, it queries mURI.
 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(BlobURL::Mutator,
                                 nsIURISetters,
                                 nsIURIMutator,
-                                nsIPrincipalURIMutator,
                                 nsISerializable)
 
 NS_IMETHODIMP
 BlobURL::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<BlobURL::Mutator> mutator = new BlobURL::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
--- a/dom/file/uri/BlobURL.h
+++ b/dom/file/uri/BlobURL.h
@@ -3,52 +3,35 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_BlobURL_h
 #define mozilla_dom_BlobURL_h
 
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/File.h"
 #include "nsCOMPtr.h"
-#include "nsIClassInfo.h"
-#include "nsIPrincipal.h"
 #include "nsISerializable.h"
-#include "nsIURIWithPrincipal.h"
 #include "nsSimpleURI.h"
 #include "nsIIPCSerializableURI.h"
-#include "nsProxyRelease.h"
+#include "prtime.h"
 
 namespace mozilla {
 namespace dom {
 
 /**
- * These URIs refer to host objects with "blob" scheme. The underlying object is
- * a BlobImpl.
+ * These URIs refer to host objects with "blob" scheme.
  */
-class BlobURL final
-  : public mozilla::net::nsSimpleURI
-  , public nsIURIWithPrincipal
+class BlobURL final : public mozilla::net::nsSimpleURI
 {
 private:
-  explicit BlobURL(nsIPrincipal* aPrincipal)
-    : mozilla::net::nsSimpleURI()
-  {
-    mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", aPrincipal, false);
-  }
-
-  // For use only from deserialization
-  explicit BlobURL()
-    : mozilla::net::nsSimpleURI()
-  {}
+  BlobURL();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIURIWITHPRINCIPAL
   NS_DECL_NSISERIALIZABLE
   NS_DECL_NSICLASSINFO
   NS_DECL_NSIIPCSERIALIZABLEURI
 
   // Override CloneInternal() and EqualsInternal()
   virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
                                  const nsACString& newRef,
                                  nsIURI** aClone) override;
@@ -60,70 +43,64 @@ public:
   virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
                                                 const nsACString& newRef) override
   {
     BlobURL* url = new BlobURL();
     SetRefOnClone(url, refHandlingMode, newRef);
     return url;
   }
 
-  NS_IMETHOD Mutate(nsIURIMutator * *_retval) override;
+  bool
+  Revoked() const
+  {
+    return mRevoked;
+  }
 
-  nsMainThreadPtrHandle<nsIPrincipal> mPrincipal;
+  NS_IMETHOD Mutate(nsIURIMutator * *_retval) override;
 
 private:
   virtual ~BlobURL() = default;
 
   nsresult SetScheme(const nsACString &aProtocol) override;
   bool Deserialize(const mozilla::ipc::URIParams&);
   nsresult ReadPrivate(nsIObjectInputStream *stream);
 
 public:
   class Mutator final
     : public nsIURIMutator
     , public BaseURIMutator<BlobURL>
-    , public nsIPrincipalURIMutator
     , public nsISerializable
   {
     NS_DECL_ISUPPORTS
     NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
     NS_DEFINE_NSIMUTATOR_COMMON
 
     NS_IMETHOD
     Write(nsIObjectOutputStream *aOutputStream) override
     {
-        return NS_ERROR_NOT_IMPLEMENTED;
+      return NS_ERROR_NOT_IMPLEMENTED;
     }
 
     MOZ_MUST_USE NS_IMETHOD
     Read(nsIObjectInputStream* aStream) override
     {
-        return InitFromInputStream(aStream);
-    }
-
-    MOZ_MUST_USE NS_IMETHOD
-    SetPrincipal(nsIPrincipal *aPrincipal) override
-    {
-        if (!mURI) {
-            return NS_ERROR_NULL_POINTER;
-        }
-        MOZ_ASSERT(NS_IsMainThread());
-        mURI->mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", aPrincipal, false);
-        return NS_OK;
+      return InitFromInputStream(aStream);
     }
 
     Mutator() = default;
 
   private:
     ~Mutator() = default;
 
     friend class BlobURL;
   };
 
   friend BaseURIMutator<BlobURL>;
+
+  bool mRevoked;
 };
 
 #define NS_HOSTOBJECTURI_CID \
 { 0xf5475c51, 0x59a7, 0x4757, \
   { 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } }
 
 #define NS_HOSTOBJECTURIMUTATOR_CID \
 { 0xbbe50ef2, 0x80eb, 0x469d, \
--- a/dom/file/uri/BlobURLChannel.cpp
+++ b/dom/file/uri/BlobURLChannel.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BlobURLChannel.h"
+#include "mozilla/dom/BlobImpl.h"
 
 using namespace mozilla::dom;
 
 BlobURLChannel::BlobURLChannel(nsIURI* aURI,
                                nsILoadInfo* aLoadInfo)
   : mInitialized(false)
 {
   SetURI(aURI);
--- a/dom/file/uri/BlobURLProtocolHandler.cpp
+++ b/dom/file/uri/BlobURLProtocolHandler.cpp
@@ -1,28 +1,29 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BlobURLProtocolHandler.h"
 #include "BlobURLChannel.h"
+#include "mozilla/dom/BlobURL.h"
 
-#include "mozilla/dom/BlobURL.h"
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/BlobImpl.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/MediaSource.h"
 #include "mozilla/ipc/IPCStreamUtils.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/ModuleUtils.h"
+#include "mozilla/NullPrincipal.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SystemGroup.h"
 #include "nsClassHashtable.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsIAsyncShutdown.h"
 #include "nsIException.h" // for nsIStackFrame
 #include "nsIMemoryReporter.h"
@@ -47,24 +48,28 @@ struct DataInfo
     eMediaSource
   };
 
   DataInfo(BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal)
     : mObjectType(eBlobImpl)
     , mBlobImpl(aBlobImpl)
     , mPrincipal(aPrincipal)
     , mRevoked(false)
-  {}
+  {
+    MOZ_ASSERT(aPrincipal);
+  }
 
   DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
     : mObjectType(eMediaSource)
     , mMediaSource(aMediaSource)
     , mPrincipal(aPrincipal)
     , mRevoked(false)
-  {}
+  {
+    MOZ_ASSERT(aPrincipal);
+  }
 
   ObjectType mObjectType;
 
   RefPtr<BlobImpl> mBlobImpl;
   RefPtr<MediaSource> mMediaSource;
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCString mStack;
@@ -131,16 +136,17 @@ GetDataInfoFromURI(nsIURI* aURI, bool aA
 // Memory reporting for the hash table.
 void
 BroadcastBlobURLRegistration(const nsACString& aURI,
                              BlobImpl* aBlobImpl,
                              nsIPrincipal* aPrincipal)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBlobImpl);
+  MOZ_ASSERT(aPrincipal);
 
   if (XRE_IsParentProcess()) {
     dom::ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
                                                      aPrincipal);
     return;
   }
 
   dom::ContentChild* cc = dom::ContentChild::GetSingleton();
@@ -401,31 +407,30 @@ NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIM
 class ReleasingTimerHolder final : public Runnable
                                  , public nsITimerCallback
                                  , public nsIAsyncShutdownBlocker
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   static void
-  Create(const nsACString& aURI, bool aBroadcastToOtherProcesses)
+  Create(const nsACString& aURI)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
-    RefPtr<ReleasingTimerHolder> holder =
-      new ReleasingTimerHolder(aURI, aBroadcastToOtherProcesses);
+    RefPtr<ReleasingTimerHolder> holder = new ReleasingTimerHolder(aURI);
 
     auto raii = MakeScopeExit([holder] {
       holder->CancelTimerAndRevokeURI();
     });
 
     nsresult rv =
       SystemGroup::EventTargetFor(TaskCategory::Other)->Dispatch(holder.forget());
     NS_ENSURE_SUCCESS_VOID(rv);
- 
+
     raii.release();
   }
 
   // Runnable interface
 
   NS_IMETHOD
   Run() override
   {
@@ -451,17 +456,17 @@ public:
     return NS_OK;
   }
 
   // nsITimerCallback interface
 
   NS_IMETHOD
   Notify(nsITimer* aTimer) override
   {
-    RevokeURI(mBroadcastToOtherProcesses);
+    RevokeURI();
     return NS_OK;
   }
 
 #ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
   using nsINamed::GetName;
 #endif
 
   // nsIAsyncShutdownBlocker interface
@@ -483,39 +488,33 @@ public:
 
   NS_IMETHOD
   GetState(nsIPropertyBag**) override
   {
     return NS_OK;
   }
 
 private:
-  ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses)
+  explicit ReleasingTimerHolder(const nsACString& aURI)
     : Runnable("ReleasingTimerHolder")
     , mURI(aURI)
-    , mBroadcastToOtherProcesses(aBroadcastToOtherProcesses)
   {}
 
   ~ReleasingTimerHolder()
   {}
 
   void
-  RevokeURI(bool aBroadcastToOtherProcesses)
+  RevokeURI()
   {
     // Remove the shutting down blocker
     nsCOMPtr<nsIAsyncShutdownClient> phase = GetShutdownPhase();
     if (phase) {
       phase->RemoveBlocker(this);
     }
 
-    // If we have to broadcast the unregistration, let's do it now.
-    if (aBroadcastToOtherProcesses) {
-      BroadcastBlobURLUnregistration(mURI);
-    }
-
     DataInfo* info = GetDataInfo(mURI, true /* We care about revoked dataInfo */);
     if (!info) {
       // Already gone!
       return;
     }
 
     MOZ_ASSERT(info->mRevoked);
 
@@ -529,35 +528,33 @@ private:
   void
   CancelTimerAndRevokeURI()
   {
     if (mTimer) {
       mTimer->Cancel();
       mTimer = nullptr;
     }
 
-    RevokeURI(false /* aBroadcastToOtherProcesses */);
+    RevokeURI();
   }
 
   static nsCOMPtr<nsIAsyncShutdownClient>
   GetShutdownPhase()
   {
     nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
     NS_ENSURE_TRUE(!!svc, nullptr);
 
     nsCOMPtr<nsIAsyncShutdownClient> phase;
     nsresult rv = svc->GetXpcomWillShutdown(getter_AddRefs(phase));
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     return phase;
   }
 
   nsCString mURI;
-  bool mBroadcastToOtherProcesses;
-
   nsCOMPtr<nsITimer> mTimer;
 };
 
 NS_IMPL_ISUPPORTS_INHERITED(ReleasingTimerHolder, Runnable, nsITimerCallback,
                             nsIAsyncShutdownBlocker)
 
 template<typename T>
 static nsresult
@@ -593,16 +590,19 @@ BlobURLProtocolHandler::BlobURLProtocolH
 
 BlobURLProtocolHandler::~BlobURLProtocolHandler() = default;
 
 /* static */ nsresult
 BlobURLProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
                                      nsIPrincipal* aPrincipal,
                                      nsACString& aUri)
 {
+  MOZ_ASSERT(aBlobImpl);
+  MOZ_ASSERT(aPrincipal);
+
   Init();
 
   nsresult rv = GenerateURIString(aPrincipal, aUri);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = AddDataEntryInternal(aUri, aBlobImpl, aPrincipal);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -610,32 +610,38 @@ BlobURLProtocolHandler::AddDataEntry(Blo
   return NS_OK;
 }
 
 /* static */ nsresult
 BlobURLProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
                                      nsIPrincipal* aPrincipal,
                                      nsACString& aUri)
 {
+  MOZ_ASSERT(aMediaSource);
+  MOZ_ASSERT(aPrincipal);
+
   Init();
 
   nsresult rv = GenerateURIString(aPrincipal, aUri);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = AddDataEntryInternal(aUri, aMediaSource, aPrincipal);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 /* static */ nsresult
 BlobURLProtocolHandler::AddDataEntry(const nsACString& aURI,
                                      nsIPrincipal* aPrincipal,
                                      BlobImpl* aBlobImpl)
 {
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(aBlobImpl);
+
   return AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
 }
 
 /* static */ bool
 BlobURLProtocolHandler::GetAllBlobURLEntries(nsTArray<BlobURLRegistrationData>& aRegistrations,
                                              ContentParent* aCP)
 {
   MOZ_ASSERT(aCP);
@@ -678,22 +684,24 @@ BlobURLProtocolHandler::RemoveDataEntry(
 
   DataInfo* info = GetDataInfo(aUri);
   if (!info) {
     return;
   }
 
   info->mRevoked = true;
 
+  if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
+    BroadcastBlobURLUnregistration(nsCString(aUri));
+  }
+
   // The timer will take care of removing the entry for real after
   // RELEASING_TIMER milliseconds. In the meantime, the DataInfo, marked as
   // revoked, will not be exposed.
-  ReleasingTimerHolder::Create(aUri,
-                               aBroadcastToOtherProcesses &&
-                                 info->mObjectType == DataInfo::eBlobImpl);
+  ReleasingTimerHolder::Create(aUri);
 }
 
 /* static */ void
 BlobURLProtocolHandler::RemoveDataEntries()
 {
   if (!gDataTable) {
     return;
   }
@@ -812,92 +820,88 @@ BlobURLProtocolHandler::GetFlagsForURI(n
 
 NS_IMETHODIMP
 BlobURLProtocolHandler::NewURI(const nsACString& aSpec,
                                const char *aCharset,
                                nsIURI *aBaseURI,
                                nsIURI **aResult)
 {
   *aResult = nullptr;
-  nsresult rv;
-
-  DataInfo* info = GetDataInfo(aSpec);
 
-  nsCOMPtr<nsIPrincipal> principal;
-  RefPtr<BlobImpl> blob;
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = NS_MutateURI(new BlobURL::Mutator())
+                  .SetSpec(aSpec)
+                  .Finalize(uri);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool revoked = true;
+  DataInfo* info = GetDataInfo(aSpec);
   if (info && info->mObjectType == DataInfo::eBlobImpl) {
-    MOZ_ASSERT(info->mBlobImpl);
-    principal = info->mPrincipal;
-    blob = info->mBlobImpl;
+    revoked = info->mRevoked;
   }
 
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_MutateURI(new BlobURL::Mutator())
-         .SetSpec(aSpec)
-         .Apply(NS_MutatorMethod(&nsIPrincipalURIMutator::SetPrincipal, principal))
-         .Finalize(uri);
+  RefPtr<BlobURL> blobURL;
+  rv = uri->QueryInterface(kHOSTOBJECTURICID,
+                           getter_AddRefs(blobURL));
   NS_ENSURE_SUCCESS(rv, rv);
 
+  MOZ_ASSERT(blobURL);
+  blobURL->mRevoked = revoked;
+
   uri.forget(aResult);
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BlobURLProtocolHandler::NewChannel2(nsIURI* aURI,
                                     nsILoadInfo* aLoadInfo,
                                     nsIChannel** aResult)
 {
   RefPtr<BlobURLChannel> channel = new BlobURLChannel(aURI, aLoadInfo);
 
   auto raii = MakeScopeExit([&] {
     channel->InitFailed();
     channel.forget(aResult);
   });
 
+  RefPtr<BlobURL> blobURL;
+  nsresult rv = aURI->QueryInterface(kHOSTOBJECTURICID,
+                                     getter_AddRefs(blobURL));
+  if (NS_FAILED(rv) || !blobURL) {
+    return NS_OK;
+  }
+
   DataInfo* info = GetDataInfoFromURI(aURI, true /*aAlsoIfRevoked */);
   if (!info || info->mObjectType != DataInfo::eBlobImpl || !info->mBlobImpl) {
     return NS_OK;
   }
 
-  RefPtr<BlobImpl> blobImpl = info->mBlobImpl;
-  nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
-  if (!uriPrinc) {
+  if (blobURL->Revoked()) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsIPrincipal> principal;
-  nsresult rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
-  NS_ENSURE_SUCCESS(rv, NS_OK);
-
-  if (!principal) {
-    return NS_OK;
-  }
-
-  MOZ_ASSERT(info->mPrincipal == principal);
-
   // We want to be sure that we stop the creation of the channel if the blob URL
   // is copy-and-pasted on a different context (ex. private browsing or
   // containers).
   //
   // We also allow the system principal to create the channel regardless of the
   // OriginAttributes.  This is primarily for the benefit of mechanisms like
   // the Download API that explicitly create a channel with the system
   // principal and which is never mutated to have a non-zero mPrivateBrowsingId
   // or container.
   if (aLoadInfo &&
       !nsContentUtils::IsSystemPrincipal(aLoadInfo->LoadingPrincipal()) &&
       !ChromeUtils::IsOriginAttributesEqualIgnoringFPD(aLoadInfo->GetOriginAttributes(),
-                                                         BasePrincipal::Cast(principal)->OriginAttributesRef())) {
+                                                       BasePrincipal::Cast(info->mPrincipal)->OriginAttributesRef())) {
     return NS_OK;
   }
 
   raii.release();
 
-  channel->Initialize(blobImpl);
+  channel->Initialize(info->mBlobImpl);
   channel.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BlobURLProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
 {
   return NewChannel2(uri, nullptr, result);
@@ -914,16 +918,48 @@ BlobURLProtocolHandler::AllowPort(int32_
 
 NS_IMETHODIMP
 BlobURLProtocolHandler::GetScheme(nsACString &result)
 {
   result.AssignLiteral(BLOBURI_SCHEME);
   return NS_OK;
 }
 
+/* static */ bool
+BlobURLProtocolHandler::GetBlobURLPrincipal(nsIURI* aURI,
+                                            nsIPrincipal** aPrincipal)
+{
+  MOZ_ASSERT(aURI);
+  MOZ_ASSERT(aPrincipal);
+
+  RefPtr<BlobURL> blobURL;
+  nsresult rv = aURI->QueryInterface(kHOSTOBJECTURICID,
+                                     getter_AddRefs(blobURL));
+  if (NS_FAILED(rv) || !blobURL) {
+    return false;
+  }
+
+  DataInfo* info = GetDataInfoFromURI(aURI, true /*aAlsoIfRevoked */);
+  if (!info || info->mObjectType != DataInfo::eBlobImpl || !info->mBlobImpl) {
+    return false;
+  }
+
+  nsCOMPtr<nsIPrincipal> principal;
+
+  if (blobURL->Revoked()) {
+    principal =
+      NullPrincipal::Create(BasePrincipal::Cast(info->mPrincipal)->OriginAttributesRef());
+  } else {
+    principal = info->mPrincipal;
+  }
+
+  principal.forget(aPrincipal);
+  return true;
+}
+
 } // dom namespace
 } // mozilla namespace
 
 nsresult
 NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
 {
   *aBlob = nullptr;
 
--- a/dom/file/uri/BlobURLProtocolHandler.h
+++ b/dom/file/uri/BlobURLProtocolHandler.h
@@ -48,30 +48,49 @@ public:
   static nsresult AddDataEntry(mozilla::dom::MediaSource* aMediaSource,
                                nsIPrincipal* aPrincipal,
                                nsACString& aUri);
   // IPC only
   static nsresult AddDataEntry(const nsACString& aURI,
                                nsIPrincipal* aPrincipal,
                                mozilla::dom::BlobImpl* aBlobImpl);
 
+  // This method revokes a blobURL. Because some operations could still be in
+  // progress, the revoking consists in marking the blobURL as revoked and in
+  // removing it after RELEASING_TIMER milliseconds.
   static void RemoveDataEntry(const nsACString& aUri,
                               bool aBroadcastToOTherProcesses = true);
 
   static void RemoveDataEntries();
 
   static bool HasDataEntry(const nsACString& aUri);
 
   static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
   static void Traverse(const nsACString& aUri, nsCycleCollectionTraversalCallback& aCallback);
 
   static bool
   GetAllBlobURLEntries(nsTArray<mozilla::dom::BlobURLRegistrationData>& aRegistrations,
                        mozilla::dom::ContentParent* aCP);
 
+  // This method returns false if aURI is not a known BlobURL. Otherwise it
+  // returns true.
+  // 
+  // When true is returned, the aPrincipal out param is meaningful.  It gets
+  // set to the principal that a channel loaded from the blob would get if
+  // the blob is not already revoked and to a NullPrincipal if the blob is
+  // revoked.
+  //
+  // This means that for a revoked blob URL this method may either return
+  // false or return true and hand out a NullPrincipal in aPrincipal,
+  // depending on whether the "remove it from the hashtable" timer has
+  // fired.  See RemoveDataEntry().
+  static bool
+  GetBlobURLPrincipal(nsIURI* aURI,
+                      nsIPrincipal** aPrincipal);
+
 private:
   ~BlobURLProtocolHandler();
 
   static void Init();
 
   // If principal is not null, its origin will be used to generate the URI.
   static nsresult GenerateURIString(nsIPrincipal* aPrincipal,
                                     nsACString &aUri);
--- a/ipc/glue/URIParams.ipdlh
+++ b/ipc/glue/URIParams.ipdlh
@@ -66,17 +66,17 @@ struct IconURIParams
 struct NullPrincipalURIParams
 {
   // Purposefully empty. Null principal URIs do not round-trip.
 };
 
 struct HostObjectURIParams
 {
   SimpleURIParams simpleParams;
-  OptionalPrincipalInfo principal;
+  bool revoked;
 };
 
 union URIParams
 {
   SimpleURIParams;
   StandardURLParams;
   JARURIParams;
   IconURIParams;
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -121,17 +121,16 @@ XPIDL_SOURCES += [
     'nsITraceableChannel.idl',
     'nsITransport.idl',
     'nsIUDPSocket.idl',
     'nsIUploadChannel.idl',
     'nsIUploadChannel2.idl',
     'nsIURI.idl',
     'nsIURIClassifier.idl',
     'nsIURIMutator.idl',
-    'nsIURIWithPrincipal.idl',
     'nsIURL.idl',
     'nsIURLParser.idl',
     'nsPILoadGroupInternal.idl',
     'nsPISocketTransportService.idl',
 ]
 
 if CONFIG['MOZ_TOOLKIT_SEARCH']:
     XPIDL_SOURCES += [
deleted file mode 100644
--- a/netwerk/base/nsIURIWithPrincipal.idl
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface nsIPrincipal;
-interface nsIURI;
-interface nsIURIMutator;
-
-/**
- * nsIURIWithPrincipal is implemented by URIs which are associated with a
- * specific principal.
- */
-[scriptable, builtinclass, uuid(626a5c0c-bfd8-4531-8b47-a8451b0daa33)]
-interface nsIURIWithPrincipal : nsISupports
-{
-    /**
-     * The principal associated with the resource returned when loading this
-     * uri.
-     */
-    readonly attribute nsIPrincipal principal;
-
-    /**
-     * The uri for the principal.
-     */
-    readonly attribute nsIURI principalUri;
-};
-
-[builtinclass, uuid(fa138a89-c76e-4b7f-95ec-c7b56ded5ef5)]
-interface nsIPrincipalURIMutator : nsISupports
-{
-    /**
-     * Associates a principal to the mutated URI.
-     * Would normally return nsIURIMutator, but since it only gets called
-     * from C++, there is no need for that.
-     */
-    [must_use, noscript] void setPrincipal(in nsIPrincipal aPrincipal);
-};
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -56,39 +56,40 @@
 #include "nsISocketProviderService.h"
 #include "nsIStandardURL.h"
 #include "nsIStreamLoader.h"
 #include "nsIIncrementalStreamLoader.h"
 #include "nsIStreamTransportService.h"
 #include "nsStringStream.h"
 #include "nsISyncStreamListener.h"
 #include "nsITransport.h"
-#include "nsIURIWithPrincipal.h"
 #include "nsIURLParser.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIViewSourceChannel.h"
 #include "nsInterfaceRequestorAgg.h"
 #include "plstr.h"
 #include "nsINestedURI.h"
 #include "mozilla/dom/nsCSPUtils.h"
+#include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/net/HttpBaseChannel.h"
 #include "nsIScriptError.h"
 #include "nsISiteSecurityService.h"
 #include "nsHttpHandler.h"
 #include "nsNSSComponent.h"
 #include "nsIRedirectHistoryEntry.h"
 #include "nsICertBlocklist.h"
 #include "nsICertOverrideService.h"
 #include "nsQueryObject.h"
 #include "mozIThirdPartyUtil.h"
 
 #include <limits>
 
 using namespace mozilla;
 using namespace mozilla::net;
+using mozilla::dom::BlobURLProtocolHandler;
 using mozilla::dom::ClientInfo;
 using mozilla::dom::PerformanceStorage;
 using mozilla::dom::ServiceWorkerDescriptor;
 
 #define DEFAULT_RP 3
 #define DEFAULT_PRIVATE_RP 2
 
 static uint32_t sDefaultRp = DEFAULT_RP;
@@ -2476,25 +2477,34 @@ NS_SecurityCompareURIs(nsIURI *aSourceUR
     {
         return false;
     }
 
     // If either URI is a nested URI, get the base URI
     nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
     nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
 
-    // If either uri is an nsIURIWithPrincipal
-    nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(sourceBaseURI);
-    if (uriPrinc) {
-        uriPrinc->GetPrincipalUri(getter_AddRefs(sourceBaseURI));
+    nsCOMPtr<nsIPrincipal> sourceBlobPrincipal;
+    if (BlobURLProtocolHandler::GetBlobURLPrincipal(sourceBaseURI,
+                                                    getter_AddRefs(sourceBlobPrincipal))) {
+      nsCOMPtr<nsIURI> sourceBlobOwnerURI;
+      nsresult rv = sourceBlobPrincipal->GetURI(getter_AddRefs(sourceBlobOwnerURI));
+      if (NS_SUCCEEDED(rv)) {
+        sourceBaseURI = sourceBlobOwnerURI;
+      }
     }
 
-    uriPrinc = do_QueryInterface(targetBaseURI);
-    if (uriPrinc) {
-        uriPrinc->GetPrincipalUri(getter_AddRefs(targetBaseURI));
+    nsCOMPtr<nsIPrincipal> targetBlobPrincipal;
+    if (BlobURLProtocolHandler::GetBlobURLPrincipal(targetBaseURI,
+                                                    getter_AddRefs(targetBlobPrincipal))) {
+      nsCOMPtr<nsIURI> targetBlobOwnerURI;
+      nsresult rv = targetBlobPrincipal->GetURI(getter_AddRefs(targetBlobOwnerURI));
+      if (NS_SUCCEEDED(rv)) {
+        targetBaseURI = targetBlobOwnerURI;
+      }
     }
 
     if (!sourceBaseURI || !targetBaseURI)
         return false;
 
     // Compare schemes
     nsAutoCString targetScheme;
     bool sameScheme = false;