Bug 1305237 LoadInfo changes to include all ancestors principals and window IDs, r=bz,mystor
authorevilpies@gmail.com
Tue, 10 Oct 2017 09:54:00 -0700
changeset 423077 ebd2ef6abc6a7034a0a41f5954aec6ea3793b53f
parent 423076 f5fcec1a1c2d0ef7aea81ea2f8fcdfb09d2ff3dc
child 423078 cbe84780624c45b29d8846fe95e7bbb9b64ddba3
push idunknown
push userunknown
push dateunknown
reviewersbz, mystor
bugs1305237
milestone58.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 1305237 LoadInfo changes to include all ancestors principals and window IDs, r=bz,mystor MozReview-Commit-ID: 1IMi5MqTx7o
docshell/base/nsDocShell.h
dom/base/nsDocument.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsIDocument.h
ipc/glue/BackgroundUtils.cpp
netwerk/base/LoadInfo.cpp
netwerk/base/LoadInfo.h
netwerk/base/nsILoadInfo.idl
netwerk/ipc/NeckoChannelParams.ipdlh
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -324,16 +324,38 @@ public:
    * This method steals the data from the passed-in array.
    */
   void SetAncestorPrincipals(
     nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals)
   {
     mAncestorPrincipals = mozilla::Move(aAncestorPrincipals);
   }
 
+  /**
+   * Get the list of ancestor outerWindowIDs for this docshell.  The list is meant
+   * to be the list of outer window IDs that correspond to the ancestorPrincipals
+   * above.   For each ancestor principal, we store the parent window ID.
+   */
+  const nsTArray<uint64_t>& AncestorOuterWindowIDs() const
+  {
+    return mAncestorOuterWindowIDs;
+  }
+
+  /**
+   * Set the list of ancestor outer window IDs for this docshell.  We call this
+   * from frameloader as well in order to keep the array matched with the
+   * ancestor principals.
+   *
+   * This method steals the data from the passed-in array.
+   */
+  void SetAncestorOuterWindowIDs(nsTArray<uint64_t>&& aAncestorOuterWindowIDs)
+  {
+    mAncestorOuterWindowIDs = mozilla::Move(aAncestorOuterWindowIDs);
+  }
+
 private:
   bool CanSetOriginAttributes();
 
 public:
   const mozilla::OriginAttributes&
   GetOriginAttributes()
   {
     return mOriginAttributes;
@@ -1130,16 +1152,18 @@ private:
   uint32_t mJSRunToCompletionDepth;
 
   // Whether or not touch events are overridden. Possible values are defined
   // as constants in the nsIDocShell.idl file.
   uint32_t mTouchEventsOverride;
 
   // Our list of ancestor principals.
   nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;
+  // Our list of ancestor outerWindowIDs.
+  nsTArray<uint64_t> mAncestorOuterWindowIDs;
 
   // Separate function to do the actual name (i.e. not _top, _self etc.)
   // searching for FindItemWithName.
   nsresult DoFindItemWithName(const nsAString& aName,
                               nsIDocShellTreeItem* aRequestor,
                               nsIDocShellTreeItem* aOriginalRequestor,
                               bool aSkipTabGroup,
                               nsIDocShellTreeItem** aResult);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4990,16 +4990,17 @@ nsIDocument::SetContainer(nsDocShell* aC
     if (sameTypeRoot == aContainer) {
       static_cast<nsDocument*>(this)->SetIsTopLevelContentDocument(true);
     }
 
     static_cast<nsDocument*>(this)->SetIsContentDocument(true);
   }
 
   mAncestorPrincipals = aContainer->AncestorPrincipals();
+  mAncestorOuterWindowIDs = aContainer->AncestorOuterWindowIDs();
 }
 
 nsISupports*
 nsIDocument::GetContainer() const
 {
   return static_cast<nsIDocShell*>(mDocumentContainer);
 }
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2489,17 +2489,21 @@ nsFrameLoader::MaybeCreateDocShell()
 
   // Get our parent docshell off the document of mOwnerContent
   // XXXbz this is such a total hack.... We really need to have a
   // better setup for doing this.
   nsIDocument* doc = mOwnerContent->OwnerDoc();
 
   MOZ_RELEASE_ASSERT(!doc->IsResourceDoc(), "We shouldn't even exist");
 
-  if (!(doc->IsStaticDocument() || mOwnerContent->IsInComposedDoc())) {
+  // Check if the document still has a window since it is possible for an
+  // iframe to be inserted and cause the creation of the docshell in a
+  // partially unloaded document (see Bug 1305237 comment 127).
+  if (!doc->IsStaticDocument() &&
+      (!doc->GetWindow() || !mOwnerContent->IsInComposedDoc())) {
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!doc->IsActive()) {
     // Don't allow subframe loads in non-active documents.
     // (See bug 610571 comment 5.)
     return NS_ERROR_NOT_AVAILABLE;
   }
@@ -2721,24 +2725,36 @@ nsFrameLoader::MaybeCreateDocShell()
         // and not inherited by its parent.
         attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
       }
     }
   }
 
   nsDocShell::Cast(mDocShell)->SetOriginAttributes(attrs);
 
+  // Typically there will be a window, however for some cases such as printing
+  // the document is cloned with a docshell that has no window.  We check
+  // that the window exists to ensure we don't try to gather ancestors for
+  // those cases.
+  nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
   if (!mDocShell->GetIsMozBrowser() &&
-      parentType == mDocShell->ItemType()) {
+      parentType == mDocShell->ItemType() &&
+      !doc->IsStaticDocument() && win) {
     // Propagate through the ancestor principals.
     nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
     // Make a copy, so we can modify it.
     ancestorPrincipals = doc->AncestorPrincipals();
     ancestorPrincipals.InsertElementAt(0, doc->NodePrincipal());
     nsDocShell::Cast(mDocShell)->SetAncestorPrincipals(Move(ancestorPrincipals));
+
+    // Repeat for outer window IDs.
+    nsTArray<uint64_t> ancestorOuterWindowIDs;
+    ancestorOuterWindowIDs = doc->AncestorOuterWindowIDs();
+    ancestorOuterWindowIDs.InsertElementAt(0, win->WindowID());
+    nsDocShell::Cast(mDocShell)->SetAncestorOuterWindowIDs(Move(ancestorOuterWindowIDs));
   }
 
   ReallyLoadFrameScripts();
   InitializeBrowserAPI();
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -461,16 +461,25 @@ public:
    * before people stop asking us for this information.
    */
   const nsTArray<nsCOMPtr<nsIPrincipal>>& AncestorPrincipals() const
   {
     return mAncestorPrincipals;
   }
 
   /**
+   * Get the list of ancestor outerWindowIDs for a document that correspond to
+   * the ancestor principals (see above for more details).
+   */
+  const nsTArray<uint64_t>& AncestorOuterWindowIDs() const
+  {
+    return mAncestorOuterWindowIDs;
+  }
+
+  /**
    * Return the LoadGroup for the document. May return null.
    */
   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const
   {
     nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
     return group.forget();
   }
 
@@ -3691,16 +3700,18 @@ protected:
 
   // CSP violation reports that have been buffered up due to a call to
   // StartBufferingCSPViolations.
   nsTArray<nsCOMPtr<nsIRunnable>> mBufferedCSPViolations;
 
   // List of ancestor principals.  This is set at the point a document
   // is connected to a docshell and not mutated thereafter.
   nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;
+  // List of ancestor outerWindowIDs that correspond to the ancestor principals.
+  nsTArray<uint64_t> mAncestorOuterWindowIDs;
 
   // Restyle root for servo's style system.
   //
   // We store this as an nsINode, rather than as an Element, so that we can store
   // the Document node as the restyle root if the entire document (along with all
   // document-level native-anonymous content) needs to be restyled.
   //
   // We also track which "descendant" bits (normal/animation-only/lazy-fc) the
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -365,16 +365,23 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
   nsTArray<RedirectHistoryEntryInfo> redirectChain;
   for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
        aLoadInfo->RedirectChain()) {
     RedirectHistoryEntryInfo* entry = redirectChain.AppendElement();
     rv = RHEntryToRHEntryInfo(redirectEntry, entry);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  nsTArray<PrincipalInfo> ancestorPrincipals;
+  ancestorPrincipals.SetCapacity(aLoadInfo->AncestorPrincipals().Length());
+  for (const auto& principal : aLoadInfo->AncestorPrincipals()) {
+    rv = PrincipalToPrincipalInfo(principal, ancestorPrincipals.AppendElement());
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   *aOptionalLoadInfoArgs =
     LoadInfoArgs(
       loadingPrincipalInfo,
       triggeringPrincipalInfo,
       principalToInheritInfo,
       sandboxedLoadingPrincipalInfo,
       optionalResultPrincipalURI,
       aLoadInfo->GetSecurityFlags(),
@@ -390,16 +397,18 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
       aLoadInfo->GetTopOuterWindowID(),
       aLoadInfo->GetFrameOuterWindowID(),
       aLoadInfo->GetEnforceSecurity(),
       aLoadInfo->GetInitialSecurityCheckDone(),
       aLoadInfo->GetIsInThirdPartyContext(),
       aLoadInfo->GetOriginAttributes(),
       redirectChainIncludingInternalRedirects,
       redirectChain,
+      ancestorPrincipals,
+      aLoadInfo->AncestorOuterWindowIDs(),
       aLoadInfo->CorsUnsafeHeaders(),
       aLoadInfo->GetForcePreflight(),
       aLoadInfo->GetIsPreflight(),
       aLoadInfo->GetForceHSTSPriming(),
       aLoadInfo->GetMixedContentWouldBlock(),
       aLoadInfo->GetIsHSTSPriming(),
       aLoadInfo->GetIsHSTSPrimingUpgrade()
       );
@@ -462,16 +471,25 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
   RedirectHistoryArray redirectChain;
   for (const RedirectHistoryEntryInfo& entryInfo : loadInfoArgs.redirectChain()) {
     nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
       RHEntryInfoToRHEntry(entryInfo);
     NS_ENSURE_SUCCESS(rv, rv);
     redirectChain.AppendElement(redirectHistoryEntry.forget());
   }
 
+  nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
+  ancestorPrincipals.SetCapacity(loadInfoArgs.ancestorPrincipals().Length());
+  for (const PrincipalInfo& principalInfo : loadInfoArgs.ancestorPrincipals()) {
+    nsCOMPtr<nsIPrincipal> ancestorPrincipal =
+      PrincipalInfoToPrincipal(principalInfo, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+    ancestorPrincipals.AppendElement(ancestorPrincipal.forget());
+  }
+
   nsCOMPtr<nsILoadInfo> loadInfo =
     new mozilla::LoadInfo(loadingPrincipal,
                           triggeringPrincipal,
                           principalToInherit,
                           sandboxedLoadingPrincipal,
                           resultPrincipalURI,
                           loadInfoArgs.securityFlags(),
                           loadInfoArgs.contentPolicyType(),
@@ -486,16 +504,18 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
                           loadInfoArgs.topOuterWindowID(),
                           loadInfoArgs.frameOuterWindowID(),
                           loadInfoArgs.enforceSecurity(),
                           loadInfoArgs.initialSecurityCheckDone(),
                           loadInfoArgs.isInThirdPartyContext(),
                           loadInfoArgs.originAttributes(),
                           redirectChainIncludingInternalRedirects,
                           redirectChain,
+                          Move(ancestorPrincipals),
+                          loadInfoArgs.ancestorOuterWindowIDs(),
                           loadInfoArgs.corsUnsafeHeaders(),
                           loadInfoArgs.forcePreflight(),
                           loadInfoArgs.isPreflight(),
                           loadInfoArgs.forceHSTSPriming(),
                           loadInfoArgs.mixedContentWouldBlock(),
                           loadInfoArgs.isHSTSPriming(),
                           loadInfoArgs.isHSTSPrimingUpgrade()
                           );
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -113,16 +113,19 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
       ComputeIsThirdPartyContext(contextOuter);
       mOuterWindowID = contextOuter->WindowID();
       nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
       mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
       mTopOuterWindowID = FindTopOuterWindowID(contextOuter);
     }
 
     mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
+    mAncestorPrincipals = aLoadingContext->OwnerDoc()->AncestorPrincipals();
+    mAncestorOuterWindowIDs = aLoadingContext->OwnerDoc()->AncestorOuterWindowIDs();
+    MOZ_DIAGNOSTIC_ASSERT(mAncestorPrincipals.Length() == mAncestorOuterWindowIDs.Length());
 
     // When the element being loaded is a frame, we choose the frame's window
     // for the window ID and the frame element's window as the parent
     // window. This is the behavior that Chrome exposes to add-ons.
     // NB: If the frameLoaderOwner doesn't have a frame loader, then the load
     // must be coming from an object (such as a plugin) that's loaded into it
     // instead of a document being loaded. In that case, treat this object like
     // any other non-document-loading element.
@@ -272,16 +275,19 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
   nsCOMPtr<nsPIDOMWindowOuter> parent = aOuterWindow->GetScriptableParent();
   mParentOuterWindowID = parent ? parent->WindowID() : 0;
   mTopOuterWindowID = FindTopOuterWindowID(aOuterWindow);
 
   // get the docshell from the outerwindow, and then get the originattributes
   nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
   MOZ_ASSERT(docShell);
   mOriginAttributes = nsDocShell::Cast(docShell)->GetOriginAttributes();
+  mAncestorPrincipals = nsDocShell::Cast(docShell)->AncestorPrincipals();
+  mAncestorOuterWindowIDs = nsDocShell::Cast(docShell)->AncestorOuterWindowIDs();
+  MOZ_DIAGNOSTIC_ASSERT(mAncestorPrincipals.Length() == mAncestorOuterWindowIDs.Length());
 
 #ifdef DEBUG
   if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
     MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
                "chrome docshell shouldn't have mPrivateBrowsingId set.");
   }
 #endif
 }
@@ -308,16 +314,18 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
   , mFrameOuterWindowID(rhs.mFrameOuterWindowID)
   , mEnforceSecurity(rhs.mEnforceSecurity)
   , mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone)
   , mIsThirdPartyContext(rhs.mIsThirdPartyContext)
   , mOriginAttributes(rhs.mOriginAttributes)
   , mRedirectChainIncludingInternalRedirects(
       rhs.mRedirectChainIncludingInternalRedirects)
   , mRedirectChain(rhs.mRedirectChain)
+  , mAncestorPrincipals(rhs.mAncestorPrincipals)
+  , mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs)
   , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
   , mForcePreflight(rhs.mForcePreflight)
   , mIsPreflight(rhs.mIsPreflight)
   , mForceHSTSPriming(rhs.mForceHSTSPriming)
   , mMixedContentWouldBlock(rhs.mMixedContentWouldBlock)
   , mIsHSTSPriming(rhs.mIsHSTSPriming)
   , mIsHSTSPrimingUpgrade(rhs.mIsHSTSPrimingUpgrade)
 {
@@ -341,16 +349,18 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
                    uint64_t aTopOuterWindowID,
                    uint64_t aFrameOuterWindowID,
                    bool aEnforceSecurity,
                    bool aInitialSecurityCheckDone,
                    bool aIsThirdPartyContext,
                    const OriginAttributes& aOriginAttributes,
                    RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
                    RedirectHistoryArray& aRedirectChain,
+                   nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
+                   const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
                    const nsTArray<nsCString>& aCorsUnsafeHeaders,
                    bool aForcePreflight,
                    bool aIsPreflight,
                    bool aForceHSTSPriming,
                    bool aMixedContentWouldBlock,
                    bool aIsHSTSPriming,
                    bool aIsHSTSPrimingUpgrade)
   : mLoadingPrincipal(aLoadingPrincipal)
@@ -368,16 +378,18 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mOuterWindowID(aOuterWindowID)
   , mParentOuterWindowID(aParentOuterWindowID)
   , mTopOuterWindowID(aTopOuterWindowID)
   , mFrameOuterWindowID(aFrameOuterWindowID)
   , mEnforceSecurity(aEnforceSecurity)
   , mInitialSecurityCheckDone(aInitialSecurityCheckDone)
   , mIsThirdPartyContext(aIsThirdPartyContext)
   , mOriginAttributes(aOriginAttributes)
+  , mAncestorPrincipals(Move(aAncestorPrincipals))
+  , mAncestorOuterWindowIDs(aAncestorOuterWindowIDs)
   , mCorsUnsafeHeaders(aCorsUnsafeHeaders)
   , mForcePreflight(aForcePreflight)
   , mIsPreflight(aIsPreflight)
   , mForceHSTSPriming (aForceHSTSPriming)
   , mMixedContentWouldBlock(aMixedContentWouldBlock)
   , mIsHSTSPriming(aIsHSTSPriming)
   , mIsHSTSPrimingUpgrade(aIsHSTSPrimingUpgrade)
 {
@@ -909,16 +921,28 @@ LoadInfo::GetRedirectChain(JSContext* aC
 }
 
 const RedirectHistoryArray&
 LoadInfo::RedirectChain()
 {
   return mRedirectChain;
 }
 
+const nsTArray<nsCOMPtr<nsIPrincipal>>&
+LoadInfo::AncestorPrincipals()
+{
+  return mAncestorPrincipals;
+}
+
+const nsTArray<uint64_t>&
+LoadInfo::AncestorOuterWindowIDs()
+{
+  return mAncestorOuterWindowIDs;
+}
+
 void
 LoadInfo::SetCorsPreflightInfo(const nsTArray<nsCString>& aHeaders,
                                bool aForcePreflight)
 {
   MOZ_ASSERT(GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS);
   MOZ_ASSERT(!mInitialSecurityCheckDone);
   mCorsUnsafeHeaders = aHeaders;
   mForcePreflight = aForcePreflight;
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -110,16 +110,18 @@ private:
            uint64_t aTopOuterWindowID,
            uint64_t aFrameOuterWindowID,
            bool aEnforceSecurity,
            bool aInitialSecurityCheckDone,
            bool aIsThirdPartyRequest,
            const OriginAttributes& aOriginAttributes,
            RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
            RedirectHistoryArray& aRedirectChain,
+           nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
+           const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
            const nsTArray<nsCString>& aUnsafeHeaders,
            bool aForcePreflight,
            bool aIsPreflight,
            bool aForceHSTSPriming,
            bool aMixedContentWouldBlock,
            bool aIsHSTSPriming,
            bool aIsHSTSPrimingUpgrade);
   LoadInfo(const LoadInfo& rhs);
@@ -163,16 +165,18 @@ private:
   uint64_t                         mTopOuterWindowID;
   uint64_t                         mFrameOuterWindowID;
   bool                             mEnforceSecurity;
   bool                             mInitialSecurityCheckDone;
   bool                             mIsThirdPartyContext;
   OriginAttributes                 mOriginAttributes;
   RedirectHistoryArray             mRedirectChainIncludingInternalRedirects;
   RedirectHistoryArray             mRedirectChain;
+  nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;
+  nsTArray<uint64_t>               mAncestorOuterWindowIDs;
   nsTArray<nsCString>              mCorsUnsafeHeaders;
   bool                             mForcePreflight;
   bool                             mIsPreflight;
 
   bool                             mForceHSTSPriming : 1;
   bool                             mMixedContentWouldBlock : 1;
   bool                             mIsHSTSPriming: 1;
   bool                             mIsHSTSPrimingUpgrade: 1;
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -18,16 +18,18 @@ interface nsIURI;
 #include "mozilla/LoadTainting.h"
 #include "nsStringFwd.h"
 %}
 
 [ref] native nsIRedirectHistoryEntryArray(const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>);
 native OriginAttributes(mozilla::OriginAttributes);
 [ref] native const_OriginAttributesRef(const mozilla::OriginAttributes);
 [ref] native StringArrayRef(const nsTArray<nsCString>);
+[ref] native Uint64ArrayRef(const nsTArray<uint64_t>);
+[ref] native PrincipalArrayRef(const nsTArray<nsCOMPtr<nsIPrincipal>>);
 
 typedef unsigned long nsSecurityFlags;
 
 /**
  * The LoadInfo object contains information about a network load, why it
  * was started, and how we plan on using the resulting response.
  * If a network request is redirected, the new channel will receive a new
  * LoadInfo object. The new object will contain mostly the same
@@ -638,16 +640,46 @@ interface nsILoadInfo : nsISupports
    * A C++-friendly version of redirectChain.
    * Please note that this array has the same lifetime as the
    * loadInfo object - use with caution!
    */
   [noscript, notxpcom, nostdcall, binaryname(RedirectChain)]
   nsIRedirectHistoryEntryArray binaryRedirectChain();
 
   /**
+   * An array of nsIPrincipals which stores the principals of the parent frames,
+   * not including the frame loading this request.  The closest ancestor is at
+   * index zero and the top level ancestor is at the last index.
+   *
+   * The ancestorPrincipals[0] entry for an iframe load will be the principal of
+   * the iframe element's owner document.
+   * The ancestorPrincipals[0] entry for an image loaded in an iframe will be the
+   * principal of the iframe element's owner document.
+   *
+   * See nsIDocument::AncestorPrincipals for more information.
+   *
+   * Please note that this array has the same lifetime as the
+   * loadInfo object - use with caution!
+   */
+  [noscript, notxpcom, nostdcall]
+  PrincipalArrayRef AncestorPrincipals();
+
+
+  /**
+   * An array of outerWindowIDs which correspond to nsILoadInfo::AncestorPrincipals
+   * above.  AncestorOuterWindowIDs[0] is the outerWindowID of the frame
+   * associated with the principal at ancestorPrincipals[0], and so forth.
+   *
+   * Please note that this array has the same lifetime as the
+   * loadInfo object - use with caution!
+   */
+  [noscript, notxpcom, nostdcall]
+  Uint64ArrayRef AncestorOuterWindowIDs();
+
+  /**
    * Sets the list of unsafe headers according to CORS spec, as well as
    * potentially forces a preflight.
    * Note that you do not need to set the Content-Type header. That will be
    * automatically detected as needed.
    *
    * Only call this function when using the SEC_REQUIRE_CORS_DATA_INHERITS mode.
    */
   [noscript, notxpcom, nostdcall]
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -54,16 +54,24 @@ struct LoadInfoArgs
   uint64_t                    topOuterWindowID;
   uint64_t                    frameOuterWindowID;
   bool                        enforceSecurity;
   bool                        initialSecurityCheckDone;
   bool                        isInThirdPartyContext;
   OriginAttributes            originAttributes;
   RedirectHistoryEntryInfo[]  redirectChainIncludingInternalRedirects;
   RedirectHistoryEntryInfo[]  redirectChain;
+
+  /**
+   * Ancestor data for use with the WebRequest API.
+   * See nsILoadInfo.idl for details.
+   */
+  PrincipalInfo[]             ancestorPrincipals;
+  uint64_t[]                  ancestorOuterWindowIDs;
+
   nsCString[]                 corsUnsafeHeaders;
   bool                        forcePreflight;
   bool                        isPreflight;
   bool                        forceHSTSPriming;
   bool                        mixedContentWouldBlock;
   bool                        isHSTSPriming;
   bool                        isHSTSPrimingUpgrade;
 };