Bug 1305237 LoadInfo changes to include all ancestors principals and window IDs
MozReview-Commit-ID: 9ZLBfQno3ik
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -365,16 +365,22 @@ 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> ancestors;
+ for (const nsCOMPtr<nsIPrincipal>& principal : aLoadInfo->Ancestors()) {
+ rv = PrincipalToPrincipalInfo(principal, ancestors.AppendElement());
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
*aOptionalLoadInfoArgs =
LoadInfoArgs(
loadingPrincipalInfo,
triggeringPrincipalInfo,
principalToInheritInfo,
sandboxedLoadingPrincipalInfo,
optionalResultPrincipalURI,
aLoadInfo->GetSecurityFlags(),
@@ -389,16 +395,18 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
aLoadInfo->GetParentOuterWindowID(),
aLoadInfo->GetFrameOuterWindowID(),
aLoadInfo->GetEnforceSecurity(),
aLoadInfo->GetInitialSecurityCheckDone(),
aLoadInfo->GetIsInThirdPartyContext(),
aLoadInfo->GetOriginAttributes(),
redirectChainIncludingInternalRedirects,
redirectChain,
+ ancestors,
+ aLoadInfo->AncestorsOuterWindowIDs(),
aLoadInfo->CorsUnsafeHeaders(),
aLoadInfo->GetForcePreflight(),
aLoadInfo->GetIsPreflight(),
aLoadInfo->GetForceHSTSPriming(),
aLoadInfo->GetMixedContentWouldBlock(),
aLoadInfo->GetIsHSTSPriming(),
aLoadInfo->GetIsHSTSPrimingUpgrade()
);
@@ -461,16 +469,24 @@ 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>> ancestors;
+ for (const PrincipalInfo& principalInfo : loadInfoArgs.ancestors()) {
+ nsCOMPtr<nsIPrincipal> ancestorPrincipal =
+ PrincipalInfoToPrincipal(principalInfo, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ ancestors.AppendElement(ancestorPrincipal.forget());
+ }
+
nsCOMPtr<nsILoadInfo> loadInfo =
new mozilla::LoadInfo(loadingPrincipal,
triggeringPrincipal,
principalToInherit,
sandboxedLoadingPrincipal,
resultPrincipalURI,
loadInfoArgs.securityFlags(),
loadInfoArgs.contentPolicyType(),
@@ -484,16 +500,18 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
loadInfoArgs.parentOuterWindowID(),
loadInfoArgs.frameOuterWindowID(),
loadInfoArgs.enforceSecurity(),
loadInfoArgs.initialSecurityCheckDone(),
loadInfoArgs.isInThirdPartyContext(),
loadInfoArgs.originAttributes(),
redirectChainIncludingInternalRedirects,
redirectChain,
+ ancestors,
+ loadInfoArgs.ancestorsOuterWindowIDs(),
loadInfoArgs.corsUnsafeHeaders(),
loadInfoArgs.forcePreflight(),
loadInfoArgs.isPreflight(),
loadInfoArgs.forceHSTSPriming(),
loadInfoArgs.mixedContentWouldBlock(),
loadInfoArgs.isHSTSPriming(),
loadInfoArgs.isHSTSPrimingUpgrade()
);
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -97,16 +97,34 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
if (aLoadingContext) {
nsCOMPtr<nsPIDOMWindowOuter> contextOuter = aLoadingContext->OwnerDoc()->GetWindow();
if (contextOuter) {
ComputeIsThirdPartyContext(contextOuter);
mOuterWindowID = contextOuter->WindowID();
nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
+
+ nsCOMPtr<nsPIDOMWindowOuter> prevParent = contextOuter;
+ do {
+ if (!parent || prevParent == parent) {
+ break;
+ }
+
+ nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(parent);
+ if (!scriptObjPrin) {
+ break;
+ }
+
+ mAncestors.AppendElement(scriptObjPrin->GetPrincipal());
+ mAncestorsOuterWindowIDs.AppendElement(parent->WindowID());
+
+ prevParent = parent;
+ parent = parent->GetScriptableParent();
+ } while (true);
}
mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
// 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
@@ -289,16 +307,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)
+ , mAncestors(rhs.mAncestors)
+ , mAncestorsOuterWindowIDs(rhs.mAncestorsOuterWindowIDs)
, mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
, mForcePreflight(rhs.mForcePreflight)
, mIsPreflight(rhs.mIsPreflight)
, mForceHSTSPriming(rhs.mForceHSTSPriming)
, mMixedContentWouldBlock(rhs.mMixedContentWouldBlock)
, mIsHSTSPriming(rhs.mIsHSTSPriming)
, mIsHSTSPrimingUpgrade(rhs.mIsHSTSPrimingUpgrade)
{
@@ -321,16 +341,18 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
uint64_t aParentOuterWindowID,
uint64_t aFrameOuterWindowID,
bool aEnforceSecurity,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyContext,
const OriginAttributes& aOriginAttributes,
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
RedirectHistoryArray& aRedirectChain,
+ nsTArray<nsCOMPtr<nsIPrincipal>>& aAncestors,
+ const nsTArray<uint64_t>& aAncestorsOuterWindowIDs,
const nsTArray<nsCString>& aCorsUnsafeHeaders,
bool aForcePreflight,
bool aIsPreflight,
bool aForceHSTSPriming,
bool aMixedContentWouldBlock,
bool aIsHSTSPriming,
bool aIsHSTSPrimingUpgrade)
: mLoadingPrincipal(aLoadingPrincipal)
@@ -347,32 +369,34 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
, mInnerWindowID(aInnerWindowID)
, mOuterWindowID(aOuterWindowID)
, mParentOuterWindowID(aParentOuterWindowID)
, mFrameOuterWindowID(aFrameOuterWindowID)
, mEnforceSecurity(aEnforceSecurity)
, mInitialSecurityCheckDone(aInitialSecurityCheckDone)
, mIsThirdPartyContext(aIsThirdPartyContext)
, mOriginAttributes(aOriginAttributes)
+ , mAncestorsOuterWindowIDs(aAncestorsOuterWindowIDs)
, mCorsUnsafeHeaders(aCorsUnsafeHeaders)
, mForcePreflight(aForcePreflight)
, mIsPreflight(aIsPreflight)
, mForceHSTSPriming (aForceHSTSPriming)
, mMixedContentWouldBlock(aMixedContentWouldBlock)
, mIsHSTSPriming(aIsHSTSPriming)
, mIsHSTSPrimingUpgrade(aIsHSTSPrimingUpgrade)
{
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
MOZ_ASSERT(mTriggeringPrincipal);
mRedirectChainIncludingInternalRedirects.SwapElements(
aRedirectChainIncludingInternalRedirects);
mRedirectChain.SwapElements(aRedirectChain);
+ mAncestors.SwapElements(aAncestors);
}
LoadInfo::~LoadInfo()
{
}
void
LoadInfo::ComputeIsThirdPartyContext(nsPIDOMWindowOuter* aOuterWindow)
@@ -870,16 +894,46 @@ LoadInfo::GetRedirectChain(JSContext* aC
}
const RedirectHistoryArray&
LoadInfo::RedirectChain()
{
return mRedirectChain;
}
+NS_IMETHODIMP
+LoadInfo::GetAncestors(JSContext* aCx, JS::MutableHandle<JS::Value> aChain)
+{
+ if (NS_WARN_IF(!ToJSValue(aCx, mAncestors, aChain))) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ return NS_OK;
+}
+
+const nsTArray<nsCOMPtr<nsIPrincipal>>&
+LoadInfo::Ancestors()
+{
+ return mAncestors;
+}
+
+NS_IMETHODIMP
+LoadInfo::GetAncestorsOuterWindowIDs(JSContext* aCx, JS::MutableHandle<JS::Value> aChain)
+{
+ if (NS_WARN_IF(!ToJSValue(aCx, mAncestorsOuterWindowIDs, aChain))) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ return NS_OK;
+}
+
+const nsTArray<uint64_t>&
+LoadInfo::AncestorsOuterWindowIDs()
+{
+ return mAncestorsOuterWindowIDs;
+}
+
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
@@ -107,16 +107,18 @@ private:
uint64_t aParentOuterWindowID,
uint64_t aFrameOuterWindowID,
bool aEnforceSecurity,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyRequest,
const OriginAttributes& aOriginAttributes,
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
RedirectHistoryArray& aRedirectChain,
+ nsTArray<nsCOMPtr<nsIPrincipal>>& aAncestors,
+ const nsTArray<uint64_t>& aAncestorsOuterWindowIDs,
const nsTArray<nsCString>& aUnsafeHeaders,
bool aForcePreflight,
bool aIsPreflight,
bool aForceHSTSPriming,
bool aMixedContentWouldBlock,
bool aIsHSTSPriming,
bool aIsHSTSPrimingUpgrade);
LoadInfo(const LoadInfo& rhs);
@@ -158,16 +160,18 @@ private:
uint64_t mParentOuterWindowID;
uint64_t mFrameOuterWindowID;
bool mEnforceSecurity;
bool mInitialSecurityCheckDone;
bool mIsThirdPartyContext;
OriginAttributes mOriginAttributes;
RedirectHistoryArray mRedirectChainIncludingInternalRedirects;
RedirectHistoryArray mRedirectChain;
+ nsTArray<nsCOMPtr<nsIPrincipal>> mAncestors;
+ nsTArray<uint64_t> mAncestorsOuterWindowIDs;
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
@@ -19,16 +19,18 @@ interface nsIURI;
class nsCString;
%}
[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 const_nsIPrincipalArray(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
@@ -627,16 +629,51 @@ 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 all the parent frames not
+ * including the frame loading this request. Closest ancestor is at index
+ * zero, top level ancestor is last index.
+ *
+ * The ancestors[0] entry for an iframe will be the iframes parent frame.
+ * The ancestors[0] entry for an image loaded in an iframe will be the
+ * iframe's parent frame.
+ */
+ [implicit_jscontext] jsval getAncestors();
+
+ /**
+ * A C++-friendly version of ancestors.
+ * Please note that this array has the same lifetime as the
+ * loadInfo object - use with caution!
+ */
+ [noscript, notxpcom, nostdcall, binaryname(Ancestors)]
+ const_nsIPrincipalArray binaryAncestors();
+
+
+ /**
+ * An array of outer window IDs, which stores IDs for all the parent frames not
+ * including the frame loading this request. These IDs match the
+ * corresponding index in ancestors above.
+ */
+ [implicit_jscontext] jsval getAncestorsOuterWindowIDs();
+
+ /**
+ * A C++-friendly version of ancestorsOuterWindowIDs.
+ * Please note that this array has the same lifetime as the
+ * loadInfo object - use with caution!
+ */
+ [noscript, notxpcom, nostdcall, binaryname(AncestorsOuterWindowIDs)]
+ Uint64ArrayRef binaryAncestorsOuterWindowIDs();
+
+ /**
* 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,18 @@ struct LoadInfoArgs
uint64_t parentOuterWindowID;
uint64_t frameOuterWindowID;
bool enforceSecurity;
bool initialSecurityCheckDone;
bool isInThirdPartyContext;
OriginAttributes originAttributes;
RedirectHistoryEntryInfo[] redirectChainIncludingInternalRedirects;
RedirectHistoryEntryInfo[] redirectChain;
+ PrincipalInfo[] ancestors;
+ uint64_t[] ancestorsOuterWindowIDs;
nsCString[] corsUnsafeHeaders;
bool forcePreflight;
bool isPreflight;
bool forceHSTSPriming;
bool mixedContentWouldBlock;
bool isHSTSPriming;
bool isHSTSPrimingUpgrade;
};