Bug 1195173 - Apply CSP to preloaded styles within layout/style/Loader.cpp (r=bz)
☠☠ backed out by b1001182a8a2 ☠ ☠
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Tue, 26 Jan 2016 15:31:19 -0800
changeset 281936 d026d6f185ab545ef4b243d7b8daaf7d225c07ab
parent 281935 3b51d7bae8e49119a4caca5e13c6bc9106a59813
child 281937 92b7c3c6e875e719bca0f8ecbc5c492eaa10baf4
push id70978
push usermozilla@christophkerschbaumer.com
push dateWed, 27 Jan 2016 18:05:13 +0000
treeherdermozilla-inbound@92b7c3c6e875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1195173
milestone47.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 1195173 - Apply CSP to preloaded styles within layout/style/Loader.cpp (r=bz)
layout/style/Loader.cpp
layout/style/Loader.h
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1010,16 +1010,42 @@ Loader::ObsoleteSheet(nsIURI* aURI)
     nsresult rv = sheetURI->Equals(aURI, &areEqual);
     if (NS_SUCCEEDED(rv) && areEqual) {
       iter.Remove();
     }
   }
   return NS_OK;
 }
 
+nsresult
+Loader::CheckContentPolicy(nsIPrincipal* aSourcePrincipal,
+                          nsIURI* aTargetURI,
+                          nsISupports* aContext,
+                          bool aIsPreload)
+{
+  nsContentPolicyType contentPolicyType =
+    aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD
+               : nsIContentPolicy::TYPE_INTERNAL_STYLESHEET;
+
+  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
+  nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType,
+                                          aTargetURI,
+                                          aSourcePrincipal,
+                                          aContext,
+                                          NS_LITERAL_CSTRING("text/css"),
+                                          nullptr,  //extra param
+                                          &shouldLoad,
+                                          nsContentUtils::GetContentPolicy(),
+                                          nsContentUtils::GetSecurityManager());
+   if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
+     return NS_ERROR_CONTENT_BLOCKED;
+   }
+   return NS_OK;
+}
+
 /**
  * CreateSheet() creates a CSSStyleSheet object for the given URI,
  * if any.  If there is no URI given, we just create a new style sheet
  * object.  Otherwise, we check for an existing style sheet object for
  * that uri in various caches and clone it if we find it.  Cloned
  * sheets will have the title/media/enabled state of the sheet they
  * are clones off; make sure to call PrepareSheet() on the result of
  * CreateSheet().
@@ -1986,22 +2012,25 @@ Loader::LoadStyleLink(nsIContent* aEleme
   nsIPrincipal* principal =
     aElement ? aElement->NodePrincipal() : mDocument->NodePrincipal();
 
   nsISupports* context = aElement;
   if (!context) {
     context = mDocument;
   }
 
+  nsresult rv = CheckContentPolicy(principal, aURL, context, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   StyleSheetState state;
   RefPtr<CSSStyleSheet> sheet;
-  nsresult rv = CreateSheet(aURL, aElement, principal, aCORSMode,
-                            aReferrerPolicy, aIntegrity, false,
-                            aHasAlternateRel, aTitle, state, aIsAlternate,
-                            getter_AddRefs(sheet));
+  rv = CreateSheet(aURL, aElement, principal, aCORSMode,
+                   aReferrerPolicy, aIntegrity, false,
+                   aHasAlternateRel, aTitle, state, aIsAlternate,
+                   getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
 
   LOG(("  Sheet is alternate: %d", *aIsAlternate));
 
   PrepareSheet(sheet, aTitle, aMedia, nullptr, nullptr, *aIsAlternate);
 
   rv = InsertSheetInDoc(sheet, aElement, mDocument);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -2115,16 +2144,20 @@ Loader::LoadChildSheet(CSSStyleSheet* aP
     topSheet->GetOwnerNode(getter_AddRefs(owningNode));
   }
 
   nsISupports* context = owningNode;
   if (!context) {
     context = mDocument;
   }
 
+  nsIPrincipal* principal = aParentSheet->Principal();
+  nsresult rv = CheckContentPolicy(principal, aURL, context, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   SheetLoadData* parentData = nullptr;
   nsCOMPtr<nsICSSLoaderObserver> observer;
 
   int32_t count = mParsingDatas.Length();
   if (count > 0) {
     LOG(("  Have a parent load"));
     parentData = mParsingDatas.ElementAt(count - 1);
     // Check for cycles
@@ -2141,19 +2174,17 @@ Loader::LoadChildSheet(CSSStyleSheet* aP
     LOG(("  No parent load; must be CSSOM"));
     // No parent load data, so the sheet will need to be notified when
     // we finish, if it can be, if we do the load asynchronously.
     observer = aParentSheet;
   }
 
   // Now that we know it's safe to load this (passes security check and not a
   // loop) do so.
-  nsIPrincipal* principal = aParentSheet->Principal();
   RefPtr<CSSStyleSheet> sheet;
-  nsresult rv;
   StyleSheetState state;
   if (aReusableSheets && aReusableSheets->FindReusableStyleSheet(aURL, sheet)) {
     aParentRule->SetSheet(sheet);
     state = eSheetComplete;
   } else {
     bool isAlternate;
     const nsSubstring& empty = EmptyString();
     // For now, use CORS_NONE for child sheets
@@ -2267,22 +2298,24 @@ Loader::InternalLoadNonDocumentSheet(nsI
     *aSheet = nullptr;
   }
 
   if (!mEnabled) {
     LOG_WARN(("  Not enabled"));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  nsresult rv = CheckContentPolicy(aOriginPrincipal, aURL, mDocument, aIsPreload);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   StyleSheetState state;
   bool isAlternate;
   RefPtr<CSSStyleSheet> sheet;
   bool syncLoad = (aObserver == nullptr);
   const nsSubstring& empty = EmptyString();
-  nsresult rv;
 
   rv = CreateSheet(aURL, nullptr, aOriginPrincipal, aCORSMode,
                    aReferrerPolicy, aIntegrity, syncLoad, false,
                    empty, state, &isAlternate, getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PrepareSheet(sheet, empty, empty, nullptr, nullptr, isAlternate);
 
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -441,16 +441,21 @@ public:
 private:
   friend class SheetLoadData;
 
   static PLDHashOperator
   RemoveEntriesWithURI(URIPrincipalReferrerPolicyAndCORSModeHashKey* aKey,
                        RefPtr<CSSStyleSheet>& aSheet,
                        void* aUserData);
 
+  nsresult CheckContentPolicy(nsIPrincipal* aSourcePrincipal,
+                              nsIURI* aTargetURI,
+                              nsISupports* aContext,
+                              bool aIsPreload);
+
   // For inline style, the aURI param is null, but the aLinkingContent
   // must be non-null then.  The loader principal must never be null
   // if aURI is not null.
   // *aIsAlternate is set based on aTitle and aHasAlternateRel.
   nsresult CreateSheet(nsIURI* aURI,
                        nsIContent* aLinkingContent,
                        nsIPrincipal* aLoaderPrincipal,
                        CORSMode aCORSMode,