Bug 1307736 - Ensure History loads pass valid triggeringPrincipal. r=bz
☠☠ backed out by 28ace1abfb5c ☠ ☠
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Mon, 16 Jan 2017 18:18:54 +0100
changeset 374607 1a71a0d9aa90635e6a4ef7e0df5272c52fd0ae54
parent 374595 99ea5dbd29164d1d0a9bc3397b9ae5e1e57290be
child 374608 338dd2c343f839e153cacb1510cbc6d31f71d6fc
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1307736
milestone53.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 1307736 - Ensure History loads pass valid triggeringPrincipal. r=bz
docshell/base/nsDocShell.cpp
docshell/shistory/nsSHEntry.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9081,39 +9081,47 @@ nsDocShell::CreateContentViewer(const ns
 
     nsIDocument* doc = viewer->GetDocument();
     if (doc) {
       doc->SetFailedChannel(failedChannel);
     }
 
     // Make sure we have a URI to set currentURI.
     nsCOMPtr<nsIURI> failedURI;
+    nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     if (failedChannel) {
       NS_GetFinalChannelURI(failedChannel, getter_AddRefs(failedURI));
     }
+    else {
+      // if there is no failed channel we have to explicitly provide
+      // a triggeringPrincipal for the history entry.
+      triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
+    }
 
     if (!failedURI) {
       failedURI = mFailedURI;
     }
+
     if (!failedURI) {
       // We need a URI object to store a session history entry, so make up a URI
       NS_NewURI(getter_AddRefs(failedURI), "about:blank");
     }
 
     // When we don't have failedURI, something wrong will happen. See
     // bug 291876.
     MOZ_ASSERT(failedURI, "We don't have a URI for history APIs.");
 
     mFailedChannel = nullptr;
     mFailedURI = nullptr;
 
     // Create an shistory entry for the old load.
     if (failedURI) {
       bool errorOnLocationChangeNeeded = OnNewURI(
-        failedURI, failedChannel, nullptr, nullptr, mLoadType, false, false, false);
+        failedURI, failedChannel, triggeringPrincipal, nullptr,
+        mLoadType, false, false, false);
 
       if (errorOnLocationChangeNeeded) {
         FireOnLocationChange(this, failedChannel, failedURI,
                              LOCATION_CHANGE_ERROR_PAGE);
       }
     }
 
     // Be sure to have a correct mLSHE, it may have been cleared by
@@ -11988,18 +11996,19 @@ nsDocShell::AddState(JS::Handle<JS::Valu
     GetCurScrollPos(ScrollOrientation_Y, &cy);
     mOSHE->SetScrollPosition(cx, cy);
 
     bool scrollRestorationIsManual = false;
     mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
 
     // Since we're not changing which page we have loaded, pass
     // true for aCloneChildren.
-    rv = AddToSessionHistory(newURI, nullptr, nullptr, nullptr, true,
-                             getter_AddRefs(newSHEntry));
+    rv = AddToSessionHistory(newURI, nullptr, 
+                             document->NodePrincipal(), // triggeringPrincipal
+                             nullptr, true, getter_AddRefs(newSHEntry));
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE);
 
     // Session history entries created by pushState inherit scroll restoration
     // mode from the current entry.
     newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual);
 
@@ -12513,22 +12522,21 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
   if (isSrcdoc) {
     aEntry->GetSrcdocData(srcdoc);
     aEntry->GetBaseURI(getter_AddRefs(baseURI));
     flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
   } else {
     srcdoc = NullString();
   }
 
-  // If there is no triggeringPrincipal we can fall back to using the
-  // SystemPrincipal as the triggeringPrincipal for loading the history
-  // entry, since the history entry can only end up in history if security
-  // checks passed in the initial loading phase.
+  // If there is no valid triggeringPrincipal, we deny the load
+  MOZ_ASSERT(triggeringPrincipal,
+             "need a valid triggeringPrincipal to load from history");
   if (!triggeringPrincipal) {
-    triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
+    return NS_ERROR_FAILURE;
   }
 
   // Passing nullptr as aSourceDocShell gives the same behaviour as before
   // aSourceDocShell was introduced. According to spec we should be passing
   // the source browsing context that was used when the history entry was
   // first created. bug 947716 has been created to address this issue.
   rv = InternalLoad(uri,
                     originalURI,
--- a/docshell/shistory/nsSHEntry.cpp
+++ b/docshell/shistory/nsSHEntry.cpp
@@ -411,16 +411,19 @@ nsSHEntry::Create(nsIURI* aURI, const ns
                   nsIInputStream* aInputStream,
                   nsILayoutHistoryState* aLayoutHistoryState,
                   nsISupports* aCacheKey, const nsACString& aContentType,
                   nsIPrincipal* aTriggeringPrincipal,
                   nsIPrincipal* aPrincipalToInherit,
                   const nsID& aDocShellID,
                   bool aDynamicCreation)
 {
+  MOZ_ASSERT(aTriggeringPrincipal,
+             "need a valid triggeringPrincipal to create a session history entry");
+
   mURI = aURI;
   mTitle = aTitle;
   mPostData = aInputStream;
 
   // Set the LoadType by default to loadHistory during creation
   mLoadType = (uint32_t)nsIDocShellLoadInfo::loadHistory;
 
   mShared->mCacheKey = aCacheKey;
@@ -510,16 +513,20 @@ nsSHEntry::GetTriggeringPrincipal(nsIPri
 {
   NS_IF_ADDREF(*aTriggeringPrincipal = mShared->mTriggeringPrincipal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSHEntry::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal)
 {
+  MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal");
+  if (!aTriggeringPrincipal) {
+    return NS_ERROR_FAILURE;
+  }
   mShared->mTriggeringPrincipal = aTriggeringPrincipal;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSHEntry::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit)
 {
   NS_IF_ADDREF(*aPrincipalToInherit = mShared->mPrincipalToInherit);