Bug 1377426 - Set CSP on freshly created nullprincipal when iframe is sandboxed. r=dveditz, a=gchang
☠☠ backed out by d7df868ad9f5 ☠ ☠
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Tue, 11 Jul 2017 08:48:37 +0200
changeset 356122 79adc16a40b7
parent 356121 7c095249ef8a
child 356123 b6c9427fffe9
push id7216
push userryanvm@gmail.com
push dateWed, 19 Jul 2017 21:02:24 +0000
treeherdermozilla-esr52@79adc16a40b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdveditz, gchang
bugs1377426
milestone52.2.1
Bug 1377426 - Set CSP on freshly created nullprincipal when iframe is sandboxed. r=dveditz, a=gchang
dom/base/nsDocument.cpp
dom/security/test/csp/test_sandbox.html
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -97,16 +97,17 @@
 #include "nsNetUtil.h"     // for NS_NewURI
 #include "nsIInputStreamChannel.h"
 #include "nsIAuthPrompt.h"
 #include "nsIAuthPrompt2.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrincipal.h"
+#include "nsNullPrincipal.h"
 
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsFocusManager.h"
 
 // for radio group stuff
 #include "nsIDOMHTMLInputElement.h"
@@ -2645,20 +2646,24 @@ nsDocument::InitCSP(nsIChannel* aChannel
   // directive, intersect the CSP sandbox flags with the existing flags. This
   // corresponds to the _least_ permissive policy.
   uint32_t cspSandboxFlags = SANDBOXED_NONE;
   rv = csp->GetCSPSandboxFlags(&cspSandboxFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mSandboxFlags |= cspSandboxFlags;
 
-  if (cspSandboxFlags & SANDBOXED_ORIGIN) {
-    // If the new CSP sandbox flags do not have the allow-same-origin flag
-    // reset the document principal to a null principal
-    principal = do_CreateInstance("@mozilla.org/nullprincipal;1");
+  // Probably the iframe sandbox attribute already caused the creation of a
+  // new NullPrincipal. Only create a new NullPrincipal if CSP requires so
+  // and no one has been created yet.
+  bool needNewNullPrincipal =
+    (cspSandboxFlags & SANDBOXED_ORIGIN) && !(mSandboxFlags & SANDBOXED_ORIGIN);
+  if (needNewNullPrincipal) {
+    principal = nsNullPrincipal::CreateWithInheritedAttributes(principal);
+    principal->SetCsp(csp);
     SetPrincipal(principal);
   }
 
   // ----- Enforce frame-ancestor policy on any applied policies
   nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell) {
     bool safeAncestry = false;
 
--- a/dom/security/test/csp/test_sandbox.html
+++ b/dom/security/test/csp/test_sandbox.html
@@ -101,16 +101,25 @@ var testCases = [
   },
   {
     // Test 12: same as Test 6
     csp: "sandbox allow-same-origin allow-scripts; default-src 'self' 'unsafe-inline';",
     file: "file_sandbox_12.html",
     results: { img12_bad: -1, script12_bad: -1 },
     nrOKmessages: 4 // sends 4 ok message
   },
+  {
+    // Test 13: same as Test 5 and Test 11, but:
+    // * using sandbox flag 'allow-scripts' in CSP and not as iframe attribute
+    // * not using allow-same-origin in CSP (so a new NullPrincipal is created).
+    csp: "default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts",
+    file: "file_sandbox_5.html",
+    results: { img13_bad: -1, img13a_bad: -1, script13_bad: -1, script13a_bad: -1 },
+    nrOKmessages: 2 // sends 2 ok message
+  },
 ];
 
 // a postMessage handler that is used by sandboxed iframes without
 // 'allow-same-origin' to communicate pass/fail back to this main page.
 // it expects to be called with an object like:
 //  { ok: true/false,
 //    desc: <description of the test> which it then forwards to ok() }
 window.addEventListener("message", receiveMessage, false);