Bug 1063837 - For xhr, don't set principal to nullprincipal in cases where we want a sandboxed document; instead, set the sandboxed flag in loadinfo. For EventSource, there is no issue iwth using system. r=sicking, smaug
authorTanvi Vyas <tvyas@mozilla.com>
Mon, 22 Sep 2014 15:34:26 -0700
changeset 206602 84c5652507ced6eed9b0d1f521c7c503213ad8a4
parent 206601 23b8b10c470622bed3aeb4483327e6fadafdf133
child 206603 de9ba02af7a66ff03493d58de550769296329783
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssicking, smaug
bugs1063837
milestone35.0a1
Bug 1063837 - For xhr, don't set principal to nullprincipal in cases where we want a sandboxed document; instead, set the sandboxed flag in loadinfo. For EventSource, there is no issue iwth using system. r=sicking, smaug
content/base/src/EventSource.cpp
content/base/src/nsXMLHttpRequest.cpp
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -748,40 +748,33 @@ EventSource::InitChannelAndRequestEventS
     channelPolicy->SetContentSecurityPolicy(csp);
     channelPolicy->SetLoadType(nsIContentPolicy::TYPE_DATAREQUEST);
   }
 
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   nsCOMPtr<nsIDocument> doc =
     nsContentUtils::GetDocumentFromScriptContext(sc);
 
-  nsCOMPtr<nsIPrincipal> principal = mPrincipal;
-  if (nsContentUtils::IsSystemPrincipal(principal)) {
-    // Don't give this channel the system principal.
-    principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
   nsCOMPtr<nsIChannel> channel;
   // If we have the document, use it
   if (doc) {
     rv = NS_NewChannel(getter_AddRefs(channel),
                        mSrc,
                        doc,
                        nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
                        nsIContentPolicy::TYPE_DATAREQUEST,
                        channelPolicy,    // aChannelPolicy
                        mLoadGroup,       // loadGroup
                        nullptr,          // aCallbacks
                        loadFlags);       // aLoadFlags
   } else {
     // otherwise use the principal
     rv = NS_NewChannel(getter_AddRefs(channel),
                        mSrc,
-                       principal,
+                       mPrincipal,
                        nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
                        nsIContentPolicy::TYPE_DATAREQUEST,
                        channelPolicy,    // aChannelPolicy
                        mLoadGroup,       // loadGroup
                        nullptr,          // aCallbacks
                        loadFlags);       // aLoadFlags
   }
 
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1730,45 +1730,45 @@ nsXMLHttpRequest::Open(const nsACString&
   rv = mPrincipal->GetCsp(getter_AddRefs(csp));
   NS_ENSURE_SUCCESS(rv, rv);
   if (csp) {
     channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
     channelPolicy->SetContentSecurityPolicy(csp);
     channelPolicy->SetLoadType(nsIContentPolicy::TYPE_XMLHTTPREQUEST);
   }
 
-  nsCOMPtr<nsIPrincipal> documentPrincipal;
+  nsSecurityFlags secFlags = nsILoadInfo::SEC_NORMAL;
   if (IsSystemXHR()) {
     // Don't give this document the system principal.  We need to keep track of
     // mPrincipal being system because we use it for various security checks
     // that should be passing, but the document data shouldn't get a system
-    // principal.
-    documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
+    // principal.  Hence we set the sandbox flag in loadinfo, so that 
+    // GetChannelResultPrincipal will give us the nullprincipal.
+    secFlags |= nsILoadInfo::SEC_SANDBOXED;
   } else {
-    documentPrincipal = mPrincipal;
+    secFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
 
   // If we have the document, use it
   if (doc) {
     rv = NS_NewChannel(getter_AddRefs(mChannel),
                        uri,
                        doc,
-                       nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                       secFlags,
                        nsIContentPolicy::TYPE_XMLHTTPREQUEST,
                        channelPolicy,
                        loadGroup,
                        nullptr,   // aCallbacks
                        nsIRequest::LOAD_BACKGROUND);
   } else {
     //otherwise use the principal
     rv = NS_NewChannel(getter_AddRefs(mChannel),
                        uri,
-                       documentPrincipal,
-                       nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                       mPrincipal,
+                       secFlags,
                        nsIContentPolicy::TYPE_XMLHTTPREQUEST,
                        channelPolicy,
                        loadGroup,
                        nullptr,   // aCallbacks
                        nsIRequest::LOAD_BACKGROUND);
   }
 
   if (NS_FAILED(rv)) return rv;
@@ -1982,29 +1982,16 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
   // Don't do anything if we have timed out.
   if (mState & XML_HTTP_REQUEST_TIMED_OUT) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
   NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
 
-  nsCOMPtr<nsIPrincipal> documentPrincipal;
-  if (IsSystemXHR()) {
-    // Don't give this document the system principal.  We need to keep track of
-    // mPrincipal being system because we use it for various security checks
-    // that should be passing, but the document data shouldn't get a system
-    // principal.
-    nsresult rv;
-    documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-  } else {
-    documentPrincipal = mPrincipal;
-  }
-
   nsresult status;
   request->GetStatus(&status);
   mErrorLoad = mErrorLoad || NS_FAILED(status);
 
   if (mUpload && !mUploadComplete && !mErrorLoad &&
       (mState & XML_HTTP_REQUEST_ASYNC)) {
     if (mProgressTimerIsActive) {
       mProgressTimerIsActive = false;
@@ -2132,31 +2119,33 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
     nsCOMPtr<nsIDocument> doc =
       nsContentUtils::GetDocumentFromScriptContext(sc);
     nsCOMPtr<nsIURI> chromeXHRDocURI, chromeXHRDocBaseURI;
     if (doc) {
       chromeXHRDocURI = doc->GetDocumentURI();
       chromeXHRDocBaseURI = doc->GetBaseURI();
     }
 
-    // Create an empty document from it.  Here we have to cheat a little bit...
-    // Setting the base URI to |baseURI| won't work if the document has a null
-    // principal, so use mPrincipal when creating the document, then reset the
-    // principal.
+    // Create an empty document from it.
     const nsAString& emptyStr = EmptyString();
     nsCOMPtr<nsIDOMDocument> responseDoc;
     nsIGlobalObject* global = DOMEventTargetHelper::GetParentObject();
+
+    nsCOMPtr<nsIPrincipal> requestingPrincipal;
+    rv = nsContentUtils::GetSecurityManager()->
+       GetChannelResultPrincipal(channel, getter_AddRefs(requestingPrincipal));
+    NS_ENSURE_SUCCESS(rv, rv);
+
     rv = NS_NewDOMDocument(getter_AddRefs(responseDoc),
                            emptyStr, emptyStr, nullptr, docURI,
-                           baseURI, mPrincipal, true, global,
+                           baseURI, requestingPrincipal, true, global,
                            mIsHtml ? DocumentFlavorHTML :
                                      DocumentFlavorLegacyGuess);
     NS_ENSURE_SUCCESS(rv, rv);
     mResponseXML = do_QueryInterface(responseDoc);
-    mResponseXML->SetPrincipal(documentPrincipal);
     mResponseXML->SetChromeXHRDocURI(chromeXHRDocURI);
     mResponseXML->SetChromeXHRDocBaseURI(chromeXHRDocBaseURI);
 
     if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
       mResponseXML->ForceEnableXULXBL();
     }
 
     if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {