Bug 927493 - Fast-path for certified apps CSP r=geekboy
authorFabrice Desré <fabrice@mozilla.com>
Thu, 17 Oct 2013 10:56:12 -0700
changeset 165035 ac2eb4f684ad92937e7c22800c4fa585f9864f4b
parent 165034 9a18ec274fed4aaee75d0628e5309a83744fba57
child 165036 e6965ee39a3890455ea966fa1c1e19720ea6d531
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgeekboy
bugs927493
milestone27.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 927493 - Fast-path for certified apps CSP r=geekboy
b2g/app/b2g.js
content/base/src/nsCSPService.cpp
content/base/src/nsCSPService.h
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -355,16 +355,17 @@ pref("content.ime.strict_policy", true);
 //
 // $ adb shell stop
 // $ adb shell setprop log.redirect-stdio true
 // $ adb shell start
 pref("browser.dom.window.dump.enabled", false);
 
 // Default Content Security Policy to apply to privileged and certified apps
 pref("security.apps.privileged.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
+// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
 pref("security.apps.certified.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self'");
 
 // Temporarily force-enable GL compositing.  This is default-disabled
 // deep within the bowels of the widgetry system.  Remove me when GL
 // compositing isn't default disabled in widget/android.
 pref("layers.acceleration.force-enabled", true);
 
 // handle links targeting new windows
--- a/content/base/src/nsCSPService.cpp
+++ b/content/base/src/nsCSPService.cpp
@@ -40,16 +40,17 @@ CSPService::CSPService()
 #ifdef PR_LOGGING
   if (!gCspPRLog)
     gCspPRLog = PR_NewLogModule("CSP");
 #endif
 }
 
 CSPService::~CSPService()
 {
+  mAppStatusCache.Clear();
 }
 
 NS_IMPL_ISUPPORTS2(CSPService, nsIContentPolicy, nsIChannelEventSink)
 
 /* nsIContentPolicy implementation */
 NS_IMETHODIMP
 CSPService::ShouldLoad(uint32_t aContentType,
                        nsIURI *aContentLocation,
@@ -100,16 +101,65 @@ CSPService::ShouldLoad(uint32_t aContent
   // TYPE_CSP_REPORT, TYPE_REFRESH, TYPE_DOCUMENT
   // (their mappings are null in contentSecurityPolicy.js)
   if (aContentType == nsIContentPolicy::TYPE_CSP_REPORT ||
     aContentType == nsIContentPolicy::TYPE_REFRESH ||
     aContentType == nsIContentPolicy::TYPE_DOCUMENT) {
     return NS_OK;
   }
 
+  // ----- THIS IS A TEMPORARY FAST PATH FOR CERTIFIED APPS. -----
+  // ----- PLEASE REMOVE ONCE bug 925004 LANDS.              -----
+
+  // Cache the app status for this origin.
+  uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  nsAutoCString contentOrigin;
+  aContentLocation->GetPrePath(contentOrigin);
+  if (aRequestPrincipal && !mAppStatusCache.Get(contentOrigin, &status)) {
+    aRequestPrincipal->GetAppStatus(&status);
+    mAppStatusCache.Put(contentOrigin, status);
+  }
+
+  if (status == nsIPrincipal::APP_STATUS_CERTIFIED) {
+    // The CSP for certified apps is :
+    // "default-src *; script-src 'self'; object-src 'none'; style-src 'self'"
+    // That means we can optimize for this case by:
+    // - loading only same origin scripts and stylesheets.
+    // - never loading objects.
+    // - accepting everything else.
+
+    switch (aContentType) {
+      case nsIContentPolicy::TYPE_SCRIPT:
+      case nsIContentPolicy::TYPE_STYLESHEET:
+        {
+          nsAutoCString sourceOrigin;
+          aRequestOrigin->GetPrePath(sourceOrigin);
+          if (!sourceOrigin.Equals(contentOrigin)) {
+            *aDecision = nsIContentPolicy::REJECT_SERVER;
+          }
+        }
+        break;
+
+      case nsIContentPolicy::TYPE_OBJECT:
+        *aDecision = nsIContentPolicy::REJECT_SERVER;
+        break;
+
+      default:
+        *aDecision = nsIContentPolicy::ACCEPT;
+    }
+
+    // Only cache and return if we are successful. If not, we want the error
+    // to be reported, and thus fallback to the slow path.
+    if (*aDecision == nsIContentPolicy::ACCEPT) {
+      return NS_OK;
+    }
+  }
+
+  // ----- END OF TEMPORARY FAST PATH FOR CERTIFIED APPS. -----
+
   // find the principal of the document that initiated this request and see
   // if it has a CSP policy object
   nsCOMPtr<nsINode> node(do_QueryInterface(aRequestContext));
   nsCOMPtr<nsIPrincipal> principal;
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   if (node) {
     principal = node->NodePrincipal();
     principal->GetCsp(getter_AddRefs(csp));
--- a/content/base/src/nsCSPService.h
+++ b/content/base/src/nsCSPService.h
@@ -18,9 +18,12 @@ class CSPService : public nsIContentPoli
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSICONTENTPOLICY
   NS_DECL_NSICHANNELEVENTSINK
 
   CSPService();
   virtual ~CSPService();
   static bool sCSPEnabled;
+private:
+  // Maps origins to app status.
+  nsDataHashtable<nsCStringHashKey, uint16_t> mAppStatusCache;
 };