Backed out changeset f4964171a9c0 (bug 994320) and changeset a4655f5da435 (bug 994318) for bustage.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 20 May 2014 14:00:26 -0400
changeset 183998 a7df548210d745224794849633339ad1cc02e7ed
parent 183997 e4e5b0502f930e2e9e16614a6580dc8272348ec9
child 183999 48a5383944fad959ab6cc569df364d21e93a00e3
push id26810
push usercbook@mozilla.com
push dateWed, 21 May 2014 11:46:36 +0000
treeherdermozilla-central@50fb8c4db2fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs994320, 994318
milestone32.0a1
backs outf4964171a9c08b310baffc670cb0355cb3cbcfb8
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
Backed out changeset f4964171a9c0 (bug 994320) and changeset a4655f5da435 (bug 994318) for bustage. CLOSED TREE
content/base/src/nsCSPContext.cpp
content/base/src/nsCSPContext.h
content/base/src/nsCSPUtils.cpp
content/base/src/nsCSPUtils.h
content/base/test/TestCSPParser.cpp
--- a/content/base/src/nsCSPContext.cpp
+++ b/content/base/src/nsCSPContext.cpp
@@ -21,17 +21,16 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIPrincipal.h"
 #include "nsIPropertyBag2.h"
 #include "nsIScriptError.h"
-#include "nsIWebNavigation.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsString.h"
 #include "prlog.h"
 
 using namespace mozilla;
 
 #if defined(PR_LOGGING)
 static PRLogModuleInfo *
@@ -41,57 +40,16 @@ GetCspContextLog()
   if (!gCspContextPRLog)
     gCspContextPRLog = PR_NewLogModule("CSPContext");
   return gCspContextPRLog;
 }
 #endif
 
 #define CSPCONTEXTLOG(args) PR_LOG(GetCspContextLog(), 4, args)
 
-static const uint32_t CSP_CACHE_URI_CUTOFF_SIZE = 512;
-
-/**
- * Creates a key for use in the ShouldLoad cache.
- * Looks like: <uri>!<nsIContentPolicy::LOAD_TYPE>
- */
-nsresult
-CreateCacheKey_Internal(nsIURI* aContentLocation,
-                        nsContentPolicyType aContentType,
-                        nsACString& outCacheKey)
-{
-  if (!aContentLocation) {
-    return NS_ERROR_FAILURE;
-  }
-
-  bool isDataScheme = false;
-  nsresult rv = aContentLocation->SchemeIs("data", &isDataScheme);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  outCacheKey.Truncate();
-  if (aContentType != nsIContentPolicy::TYPE_SCRIPT && isDataScheme) {
-    // For non-script data: URI, use ("data:", aContentType) as the cache key.
-    outCacheKey.Append(NS_LITERAL_CSTRING("data:"));
-    outCacheKey.AppendInt(aContentType);
-    return NS_OK;
-  }
-
-  nsAutoCString spec;
-  rv = aContentLocation->GetSpec(spec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Don't cache for a URI longer than the cutoff size.
-  if (spec.Length() <= CSP_CACHE_URI_CUTOFF_SIZE) {
-    outCacheKey.Append(spec);
-    outCacheKey.Append(NS_LITERAL_CSTRING("!"));
-    outCacheKey.AppendInt(aContentType);
-  }
-
-  return NS_OK;
-}
-
 /* =====  nsIContentSecurityPolicy impl ====== */
 
 NS_IMETHODIMP
 nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
                          nsIURI*             aContentLocation,
                          nsIURI*             aRequestOrigin,
                          nsISupports*        aRequestContext,
                          const nsACString&   aMimeTypeGuess,
@@ -111,26 +69,16 @@ nsCSPContext::ShouldLoad(nsContentPolicy
   // This ShouldLoad function is called from nsCSPService::ShouldLoad,
   // which already checked a number of things, including:
   // * aContentLocation is not null; we can consume this without further checks
   // * scheme is not a whitelisted scheme (about: chrome:, etc).
   // * CSP is enabled
   // * Content Type is not whitelisted (CSP Reports, TYPE_DOCUMENT, etc).
   // * Fast Path for Apps
 
-  nsAutoCString cacheKey;
-  rv = CreateCacheKey_Internal(aContentLocation, aContentType, cacheKey);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool isCached = mShouldLoadCache.Get(cacheKey, outDecision);
-  if (isCached && cacheKey.Length() > 0) {
-    // this is cached, use the cached value.
-    return NS_OK;
-  }
-
   // Default decision, CSP can revise it if there's a policy to enforce
   *outDecision = nsIContentPolicy::ACCEPT;
 
   // This may be a load or a preload. If it is a preload, the document will
   // not have been fully parsed yet, and aRequestContext will be an
   // nsIDOMHTMLDocument rather than the nsIDOMHTMLElement associated with the
   // resource. As a result, we cannot extract the element's corresponding
   // nonce attribute, and so we cannot correctly check the nonce on a preload.
@@ -184,21 +132,16 @@ nsCSPContext::ShouldLoad(nsContentPolicy
                                          violatedDirective.get());
       }
 
       // TODO: future patches fix:
       // * AsyncReportViolation, bug 994322
       // * Console error reporting, bug 994322
     }
   }
-  // Done looping, cache any relevant result
-  if (cacheKey.Length() > 0 && !isPreload) {
-    mShouldLoadCache.Put(cacheKey, *outDecision);
-  }
-
 #ifdef PR_LOGGING
   {
   nsAutoCString spec;
   aContentLocation->GetSpec(spec);
   CSPCONTEXTLOG(("nsCSPContext::ShouldLoad, decision: %s, aContentLocation: %s", *outDecision ? "load" : "deny", spec.get()));
   }
 #endif
   return NS_OK;
@@ -235,17 +178,16 @@ nsCSPContext::nsCSPContext()
 }
 
 nsCSPContext::~nsCSPContext()
 {
   CSPCONTEXTLOG(("nsCSPContext::~nsCSPContext"));
   for (uint32_t i = 0; i < mPolicies.Length(); i++) {
     delete mPolicies[i];
   }
-  mShouldLoadCache.Clear();
 }
 
 NS_IMETHODIMP
 nsCSPContext::GetIsInitialized(bool *outIsInitialized)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -268,18 +210,16 @@ nsCSPContext::GetPolicyCount(uint32_t *o
 
 NS_IMETHODIMP
 nsCSPContext::RemovePolicy(uint32_t aIndex)
 {
   if (aIndex >= mPolicies.Length()) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
   mPolicies.RemoveElementAt(aIndex);
-  // reset cache since effective policy changes
-  mShouldLoadCache.Clear();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCSPContext::AppendPolicy(const nsAString& aPolicyString,
                            nsIURI* aSelfURI,
                            bool aReportOnly,
                            bool aSpecCompliant)
@@ -292,18 +232,16 @@ nsCSPContext::AppendPolicy(const nsAStri
     NS_WARNING("aSelfURI should be a nullptr in AppendPolicy and removed in bug 991474");
   }
 
   // Use the mSelfURI from setRequestContext, see bug 991474
   NS_ASSERTION(mSelfURI, "mSelfURI required for AppendPolicy, but not set");
   nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(aPolicyString, mSelfURI, aReportOnly, 0);
   if (policy) {
     mPolicies.AppendElement(policy);
-    // reset cache since effective policy changes
-    mShouldLoadCache.Clear();
   }
   return NS_OK;
 }
 
 // aNonceOrContent either holds the nonce-value or otherwise the content
 // of the element to be hashed.
 NS_IMETHODIMP
 nsCSPContext::getAllowsInternal(nsContentPolicyType aContentType,
@@ -435,128 +373,21 @@ nsCSPContext::SetRequestContext(nsIURI* 
   NS_ASSERTION(mSelfURI, "No mSelfURI in SetRequestContext, can not translate 'self' into actual URI");
 
   // aDocumentPrincipal will be removed in bug 994872
   // aReferrer will be used in the patch for bug 994322
 
   return NS_OK;
 }
 
-/**
- * Based on the given docshell, determines if this CSP context allows the
- * ancestry.
- *
- * In order to determine the URI of the parent document (one causing the load
- * of this protected document), this function obtains the docShellTreeItem,
- * then walks up the hierarchy until it finds a privileged (chrome) tree item.
- * Getting the parent's URI looks like this in pseudocode:
- *
- * nsIDocShell->QI(nsIInterfaceRequestor)
- *            ->GI(nsIDocShellTreeItem)
- *            ->QI(nsIInterfaceRequestor)
- *            ->GI(nsIWebNavigation)
- *            ->GetCurrentURI();
- *
- * aDocShell is the docShell for the protected document.
- */
 NS_IMETHODIMP
 nsCSPContext::PermitsAncestry(nsIDocShell* aDocShell, bool* outPermitsAncestry)
 {
-  nsresult rv;
-
-  // Can't check ancestry without a docShell.
-  if (aDocShell == nullptr) {
-    return NS_ERROR_FAILURE;
-  }
-
+  // For now, we allows permitsAncestry, this will be fixed in Bug 994320
   *outPermitsAncestry = true;
-
-  // extract the ancestry as an array
-  nsCOMArray<nsIURI> ancestorsArray;
-
-  nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(aDocShell));
-  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_GetInterface(ir));
-  nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
-  nsCOMPtr<nsIWebNavigation> webNav;
-  nsCOMPtr<nsIURI> currentURI;
-  nsCOMPtr<nsIURI> uriClone;
-
-  // iterate through each docShell parent item
-  while (NS_SUCCEEDED(treeItem->GetParent(getter_AddRefs(parentTreeItem))) &&
-         parentTreeItem != nullptr) {
-    ir     = do_QueryInterface(parentTreeItem);
-    NS_ASSERTION(ir, "Could not QI docShellTreeItem to nsIInterfaceRequestor");
-
-    webNav = do_GetInterface(ir);
-    NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
-
-    rv = webNav->GetCurrentURI(getter_AddRefs(currentURI));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (currentURI) {
-      // stop when reaching chrome
-      bool isChrome = false;
-      rv = currentURI->SchemeIs("chrome", &isChrome);
-      NS_ENSURE_SUCCESS(rv, rv);
-      if (isChrome) { break; }
-
-      // delete the userpass from the URI.
-      rv = currentURI->CloneIgnoringRef(getter_AddRefs(uriClone));
-      NS_ENSURE_SUCCESS(rv, rv);
-      rv = uriClone->SetUserPass(EmptyCString());
-      NS_ENSURE_SUCCESS(rv, rv);
-#ifdef PR_LOGGING
-      {
-      nsAutoCString spec;
-      uriClone->GetSpec(spec);
-      CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, found ancestor: %s", spec.get()));
-      }
-#endif
-      ancestorsArray.AppendElement(uriClone);
-    }
-
-    // next ancestor
-    treeItem = parentTreeItem;
-  }
-
-  nsAutoString violatedDirective;
-
-  // Now that we've got the ancestry chain in ancestorsArray, time to check
-  // them against any CSP.
-  for (uint32_t i = 0; i < mPolicies.Length(); i++) {
-    for (uint32_t a = 0; a < ancestorsArray.Length(); a++) {
-      // TODO(sid) the mapping from frame-ancestors context to TYPE_DOCUMENT is
-      // forced. while this works for now, we will implement something in
-      // bug 999656.
-#ifdef PR_LOGGING
-      {
-      nsAutoCString spec;
-      ancestorsArray[a]->GetSpec(spec);
-      CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, checking ancestor: %s", spec.get()));
-      }
-#endif
-      if (!mPolicies[i]->permits(nsIContentPolicy::TYPE_DOCUMENT,
-                                 ancestorsArray[a],
-                                 EmptyString(), // no nonce
-                                 violatedDirective)) {
-        // Policy is violated
-        nsCOMPtr<nsIObserverService> observerService =
-          mozilla::services::GetObserverService();
-        NS_ENSURE_TRUE(observerService, NS_ERROR_NOT_AVAILABLE);
-
-        observerService->NotifyObservers(ancestorsArray[a],
-                                         CSP_VIOLATION_TOPIC,
-                                         violatedDirective.get());
-        // TODO(sid) generate violation reports and remove NotifyObservers
-        //           call. (in bug 994322)
-        // TODO(sid) implement logic for report-only (in bug 994322)
-        *outPermitsAncestry = false;
-      }
-    }
-  }
   return NS_OK;
 }
 
 /* ===== nsISerializable implementation ====== */
 
 NS_IMETHODIMP
 nsCSPContext::Read(nsIObjectInputStream* aStream)
 {
--- a/content/base/src/nsCSPContext.h
+++ b/content/base/src/nsCSPContext.h
@@ -2,17 +2,16 @@
 /* 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 nsCSPContext_h___
 #define nsCSPContext_h___
 
 #include "nsCSPUtils.h"
-#include "nsDataHashtable.h"
 #include "nsIChannel.h"
 #include "nsIClassInfo.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsISerializable.h"
 #include "nsXPCOM.h"
 
 #define NS_CSPCONTEXT_CONTRACTID "@mozilla.org/cspcontext;1"
  // 09d9ed1a-e5d4-4004-bfe0-27ceb923d9ac
@@ -32,14 +31,13 @@ class nsCSPContext : public nsIContentSe
 
   private:
     NS_IMETHODIMP getAllowsInternal(nsContentPolicyType aContentType,
                                     enum CSPKeyword aKeyword,
                                     const nsAString& aNonceOrContent,
                                     bool* outShouldReportViolations,
                                     bool* outIsAllowed) const;
 
-    nsTArray<nsCSPPolicy*>                     mPolicies;
-    nsCOMPtr<nsIURI>                           mSelfURI;
-    nsDataHashtable<nsCStringHashKey, int16_t> mShouldLoadCache;
+    nsTArray<nsCSPPolicy*> mPolicies;
+    nsCOMPtr<nsIURI>       mSelfURI;
 };
 
 #endif /* nsCSPContext_h___ */
--- a/content/base/src/nsCSPUtils.cpp
+++ b/content/base/src/nsCSPUtils.cpp
@@ -631,18 +631,16 @@ CSP_DirectiveToContentType(enum CSPDirec
   switch (aDir) {
     case CSP_IMG_SRC:    return nsIContentPolicy::TYPE_IMAGE;
     case CSP_SCRIPT_SRC: return nsIContentPolicy::TYPE_SCRIPT;
     case CSP_STYLE_SRC:  return nsIContentPolicy::TYPE_STYLESHEET;
     case CSP_FONT_SRC:   return nsIContentPolicy::TYPE_FONT;
     case CSP_MEDIA_SRC:  return nsIContentPolicy::TYPE_MEDIA;
     case CSP_OBJECT_SRC: return nsIContentPolicy::TYPE_OBJECT;
     case CSP_FRAME_SRC:  return nsIContentPolicy::TYPE_SUBDOCUMENT;
-    // TODO(sid): fix this mapping to be more precise (bug 999656)
-    case CSP_FRAME_ANCESTORS: return nsIContentPolicy::TYPE_DOCUMENT;
 
     // Fall through to error for the following Directives:
     case CSP_DEFAULT_SRC:
     case CSP_CONNECT_SRC:
     case CSP_REPORT_URI:
     case CSP_LAST_DIRECTIVE_VALUE:
     default:
       NS_ASSERTION(false, "Can not convert CSPDirective into nsContentPolicyType");
--- a/content/base/src/nsCSPUtils.h
+++ b/content/base/src/nsCSPUtils.h
@@ -44,34 +44,32 @@ enum CSPDirective {
   CSP_OBJECT_SRC,
   CSP_STYLE_SRC,
   CSP_IMG_SRC,
   CSP_MEDIA_SRC,
   CSP_FRAME_SRC,
   CSP_FONT_SRC,
   CSP_CONNECT_SRC,
   CSP_REPORT_URI,
-  CSP_FRAME_ANCESTORS,
   // CSP_LAST_DIRECTIVE_VALUE always needs to be the last element in the enum
   // because we use it to calculate the size for the char* array.
   CSP_LAST_DIRECTIVE_VALUE
 };
 
 static const char* CSPStrDirectives[] = {
-  "default-src",    // CSP_DEFAULT_SRC = 0
-  "script-src",     // CSP_SCRIPT_SRC
-  "object-src",     // CSP_OBJECT_SRC
-  "style-src",      // CSP_STYLE_SRC
-  "img-src",        // CSP_IMG_SRC
-  "media-src",      // CSP_MEDIA_SRC
-  "frame-src",      // CSP_FRAME_SRC
-  "font-src",       // CSP_FONT_SRC
-  "connect-src",    // CSP_CONNECT_SRC
-  "report-uri",     // CSP_REPORT_URI
-  "frame-ancestors" // CSP_FRAME_ANCESTORS
+  "default-src", // CSP_DEFAULT_SRC = 0
+  "script-src",  // CSP_SCRIPT_SRC
+  "object-src",  // CSP_OBJECT_SRC
+  "style-src",   // CSP_STYLE_SRC
+  "img-src",     // CSP_IMG_SRC
+  "media-src",   // CSP_MEDIA_SRC
+  "frame-src",   // CSP_FRAME_SRC
+  "font-src",    // CSP_FONT_SRC
+  "connect-src", // CSP_CONNECT_SRC
+  "report-uri",  // CSP_REPORT_URI
 };
 
 inline const char* CSP_EnumToDirective(enum CSPDirective aDir)
 {
   // Make sure all elements in enum CSPDirective got added to CSPStrDirectives.
   static_assert((sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]) ==
                 static_cast<uint32_t>(CSP_LAST_DIRECTIVE_VALUE)),
                 "CSP_LAST_DIRECTIVE_VALUE does not match length of CSPStrDirectives");
--- a/content/base/test/TestCSPParser.cpp
+++ b/content/base/test/TestCSPParser.cpp
@@ -662,38 +662,16 @@ nsresult TestGoodGeneratedPolicies() {
     { "default-src 'self' HTTP://foo.com",
       "default-src http://www.selfuri.com http://foo.com" },
     { "default-src 'NONE'",
       "default-src 'none'" },
     { "script-src policy-uri ",
       "script-src http://policy-uri" },
     { "img-src 'self'; ",
       "img-src http://www.selfuri.com" },
-    { "frame-ancestors foo-bar.com",
-      "frame-ancestors http://foo-bar.com" },
-    { "frame-ancestors http://a.com",
-      "frame-ancestors http://a.com" },
-    { "frame-ancestors 'self'",
-      "frame-ancestors http://www.selfuri.com" },
-    { "frame-ancestors http://self.com:88",
-      "frame-ancestors http://self.com:88" },
-    { "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com",
-      "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com" },
-    { "frame-ancestors https://self.com:34",
-      "frame-ancestors https://self.com:34" },
-    { "default-src 'none'; frame-ancestors 'self'",
-      "default-src 'none'; frame-ancestors http://www.selfuri.com" },
-    { "frame-ancestors http://self:80",
-      "frame-ancestors http://self:80" },
-    { "frame-ancestors http://self.com/bar",
-      "frame-ancestors http://self.com" },
-    { "default-src 'self'; frame-ancestors 'self'",
-      "default-src http://www.selfuri.com; frame-ancestors http://www.selfuri.com" },
-    { "frame-ancestors http://bar.com/foo.png",
-      "frame-ancestors http://bar.com" },
   };
 
   uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
   return runTestSuite(policies, policyCount, 1);
 }
 
 // ============================= TestBadGeneratedPolicies ========================