Bug 1370263: Don't try to match content scripts for non-codebase principals. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 06 Jun 2017 14:18:49 -0700
changeset 592866 da431ada55fda32be5335a18df5d925e2a84ebbb
parent 592819 03f93e71d64713c927cdad19982df2322f4007ae
child 592903 b4a6eda36c97c7521ae1db94a37721f03d63cdee
push id63526
push usermaglione.k@gmail.com
push dateMon, 12 Jun 2017 21:03:04 +0000
reviewersmixedpuppy
bugs1370263
milestone56.0a1
Bug 1370263: Don't try to match content scripts for non-codebase principals. r?mixedpuppy MozReview-Commit-ID: 96lQfKC9PGx
toolkit/components/extensions/WebExtensionContentScript.h
toolkit/components/extensions/WebExtensionPolicy.cpp
--- a/toolkit/components/extensions/WebExtensionContentScript.h
+++ b/toolkit/components/extensions/WebExtensionContentScript.h
@@ -35,18 +35,23 @@ class MOZ_STACK_CLASS DocInfo final
 {
 public:
   DocInfo(const URLInfo& aURL, nsILoadInfo* aLoadInfo);
 
   MOZ_IMPLICIT DocInfo(nsPIDOMWindowOuter* aWindow);
 
   const URLInfo& URL() const { return mURL; }
 
+  // The principal of the document, or the expected principal of a request.
+  // May be null for non-DOMWindow DocInfo objects unless
+  // URL().InheritsPrincipal() is true.
   nsIPrincipal* Principal() const;
 
+  // Returns the URL of the document's principal. Note that this must *only*
+  // be called for codebase principals.
   const URLInfo& PrincipalURL() const;
 
   bool IsTopLevel() const;
 
   uint64_t FrameID() const;
 
   nsPIDOMWindowOuter* GetWindow() const
   {
--- a/toolkit/components/extensions/WebExtensionPolicy.cpp
+++ b/toolkit/components/extensions/WebExtensionPolicy.cpp
@@ -359,20 +359,27 @@ WebExtensionContentScript::Matches(const
     return false;
   }
 
   // Top-level about:blank is a special case. We treat it as a match if
   // matchAboutBlank is true and it has the null principal. In all other
   // cases, we test the URL of the principal that it inherits.
   if (mMatchAboutBlank && aDoc.IsTopLevel() &&
       aDoc.URL().Spec().EqualsLiteral("about:blank") &&
-      aDoc.Principal()->GetIsNullPrincipal()) {
+      aDoc.Principal() && aDoc.Principal()->GetIsNullPrincipal()) {
     return true;
   }
 
+  // With the exception of top-level about:blank documents with null
+  // principals, we never match documents that have non-codebase principals,
+  // including those with null principals or system principals.
+  if (aDoc.Principal() && !aDoc.Principal()->GetIsCodebasePrincipal()) {
+    return false;
+  }
+
   return MatchesURI(aDoc.PrincipalURL());
 }
 
 bool
 WebExtensionContentScript::MatchesURI(const URLInfo& aURL) const
 {
   if (!mMatches->Matches(aURL)) {
     return false;
@@ -466,39 +473,53 @@ DocInfo::FrameID() const
 }
 
 nsIPrincipal*
 DocInfo::Principal() const
 {
   if (mPrincipal.isNothing()) {
     struct Matcher
     {
+      explicit Matcher(const DocInfo& aThis) : mThis(aThis) {}
+      const DocInfo& mThis;
+
       nsIPrincipal* match(Window aWin)
       {
         nsCOMPtr<nsIDocument> doc = aWin->GetDoc();
         return doc->NodePrincipal();
       }
-      nsIPrincipal* match(LoadInfo aLoadInfo) { return aLoadInfo->PrincipalToInherit(); }
+      nsIPrincipal* match(LoadInfo aLoadInfo)
+      {
+        if (!(mThis.URL().InheritsPrincipal() || aLoadInfo->GetForceInheritPrincipal())) {
+          return nullptr;
+        }
+        if (auto principal = aLoadInfo->PrincipalToInherit()) {
+          return principal;
+        }
+        return aLoadInfo->TriggeringPrincipal();
+      }
     };
-    mPrincipal.emplace(mObj.match(Matcher()));
+    mPrincipal.emplace(mObj.match(Matcher(*this)));
   }
   return mPrincipal.ref();
 }
 
 const URLInfo&
 DocInfo::PrincipalURL() const
 {
-  if (!URL().InheritsPrincipal()) {
+  if (!URL().InheritsPrincipal() ||
+      !(Principal() && Principal()->GetIsCodebasePrincipal())) {
     return URL();
   }
 
   if (mPrincipalURL.isNothing()) {
     nsIPrincipal* prin = Principal();
     nsCOMPtr<nsIURI> uri;
-    if (prin && NS_SUCCEEDED(prin->GetURI(getter_AddRefs(uri)))) {
+    if (NS_SUCCEEDED(prin->GetURI(getter_AddRefs(uri)))) {
+      MOZ_DIAGNOSTIC_ASSERT(uri);
       mPrincipalURL.emplace(uri);
     } else {
       mPrincipalURL.emplace(URL());
     }
   }
 
   return mPrincipalURL.ref();
 }