Bug 1532287 - P2 Propagate loading document/worker's COEP to nsHttpChannel through nsILoadInfo r=necko-reviewers,valentin,JuniorHsu

Currently, the worker's COEP is saved in WorkerPrivate and not be respected when loading resources in workers.
This patch adds an attribute loadingEmbedderPolicy in nsILoadInfo, which indicates the COEP header the loading must be respected.

The default value of loadingEmbedderPolicy is nsILoadInfo::EMBEDDER_POLICY_NULL.
loadingEmbedderPolicy is initialized with the COEP of the BrowsingContext used for creating LoadInfo.
And it could be set to other value when fetch in workers.

Differential Revision: https://phabricator.services.mozilla.com/D73690
This commit is contained in:
Eden Chuang 2020-05-19 12:50:39 +00:00
Родитель c42e8d4e87
Коммит 16b5f23697
9 изменённых файлов: 84 добавлений и 33 удалений

Просмотреть файл

@ -644,6 +644,12 @@ nsresult FetchDriver::HttpFetch(
NS_ENSURE_SUCCESS(rv, rv);
}
{
nsCOMPtr<nsILoadInfo> loadInfo = chan->LoadInfo();
rv = loadInfo->SetLoadingEmbedderPolicy(mRequest->GetEmbedderPolicy());
NS_ENSURE_SUCCESS(rv, rv);
}
// Insert ourselves into the notification callbacks chain so we can set
// headers on redirects.
#ifdef DEBUG

Просмотреть файл

@ -547,7 +547,8 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
aLoadInfo->GetParserCreatedScript(),
aLoadInfo->GetIsFromProcessingFrameAttributes(), cookieJarSettingsArgs,
aLoadInfo->GetRequestBlockingReason(), maybeCspToInheritInfo,
aLoadInfo->GetHasStoragePermission()));
aLoadInfo->GetHasStoragePermission(),
aLoadInfo->GetLoadingEmbedderPolicy()));
return NS_OK;
}
@ -769,7 +770,8 @@ nsresult LoadInfoArgsToLoadInfo(
loadInfoArgs.hasValidUserGestureActivation(),
loadInfoArgs.allowDeprecatedSystemRequests(),
loadInfoArgs.parserCreatedScript(), loadInfoArgs.hasStoragePermission(),
loadInfoArgs.requestBlockingReason(), loadingContext);
loadInfoArgs.requestBlockingReason(), loadingContext,
loadInfoArgs.loadingEmbedderPolicy());
if (loadInfoArgs.isFromProcessingFrameAttributes()) {
loadInfo->SetIsFromProcessingFrameAttributes();

Просмотреть файл

@ -111,7 +111,8 @@ LoadInfo::LoadInfo(
mAllowDeprecatedSystemRequests(false),
mParserCreatedScript(false),
mHasStoragePermission(false),
mIsFromProcessingFrameAttributes(false) {
mIsFromProcessingFrameAttributes(false),
mLoadingEmbedderPolicy(nsILoadInfo::EMBEDDER_POLICY_NULL) {
MOZ_ASSERT(mLoadingPrincipal);
MOZ_ASSERT(mTriggeringPrincipal);
@ -236,6 +237,10 @@ LoadInfo::LoadInfo(
}
mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
RefPtr<WindowContext> ctx = WindowContext::GetById(mInnerWindowID);
if (ctx) {
mLoadingEmbedderPolicy = ctx->GetEmbedderPolicy();
}
mAncestorPrincipals =
aLoadingContext->OwnerDoc()->AncestorPrincipals().Clone();
mAncestorOuterWindowIDs =
@ -388,7 +393,8 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
mAllowDeprecatedSystemRequests(false),
mParserCreatedScript(false),
mHasStoragePermission(false),
mIsFromProcessingFrameAttributes(false) {
mIsFromProcessingFrameAttributes(false),
mLoadingEmbedderPolicy(nsILoadInfo::EMBEDDER_POLICY_NULL) {
// Top-level loads are never third-party
// Grab the information we can out of the window.
MOZ_ASSERT(aOuterWindow);
@ -494,7 +500,8 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
mAllowDeprecatedSystemRequests(false),
mParserCreatedScript(false),
mHasStoragePermission(false),
mIsFromProcessingFrameAttributes(false) {
mIsFromProcessingFrameAttributes(false),
mLoadingEmbedderPolicy(nsILoadInfo::EMBEDDER_POLICY_NULL) {
// Top-level loads are never third-party
// Grab the information we can out of the window.
MOZ_ASSERT(aBrowsingContext);
@ -581,7 +588,8 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
mAllowDeprecatedSystemRequests(false),
mParserCreatedScript(false),
mHasStoragePermission(false),
mIsFromProcessingFrameAttributes(false) {
mIsFromProcessingFrameAttributes(false),
mLoadingEmbedderPolicy(nsILoadInfo::EMBEDDER_POLICY_NULL) {
RefPtr<WindowGlobalParent> parentWGP =
aBrowsingContext->GetParentWindowContext();
CanonicalBrowsingContext* parentBC = parentWGP->BrowsingContext();
@ -715,6 +723,11 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
"chrome docshell shouldn't have mPrivateBrowsingId set.");
}
RefPtr<WindowContext> ctx = WindowContext::GetById(mInnerWindowID);
if (ctx) {
mLoadingEmbedderPolicy = ctx->GetEmbedderPolicy();
}
}
LoadInfo::LoadInfo(const LoadInfo& rhs)
@ -788,7 +801,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mAllowDeprecatedSystemRequests(rhs.mAllowDeprecatedSystemRequests),
mParserCreatedScript(rhs.mParserCreatedScript),
mHasStoragePermission(rhs.mHasStoragePermission),
mIsFromProcessingFrameAttributes(rhs.mIsFromProcessingFrameAttributes) {}
mIsFromProcessingFrameAttributes(rhs.mIsFromProcessingFrameAttributes),
mLoadingEmbedderPolicy(rhs.mLoadingEmbedderPolicy) {}
LoadInfo::LoadInfo(
nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
@ -828,7 +842,8 @@ LoadInfo::LoadInfo(
uint32_t aHttpsOnlyStatus, bool aHasValidUserGestureActivation,
bool aAllowDeprecatedSystemRequests, bool aParserCreatedScript,
bool aHasStoragePermission, uint32_t aRequestBlockingReason,
nsINode* aLoadingContext)
nsINode* aLoadingContext,
nsILoadInfo::CrossOriginEmbedderPolicy aLoadingEmbedderPolicy)
: mLoadingPrincipal(aLoadingPrincipal),
mTriggeringPrincipal(aTriggeringPrincipal),
mPrincipalToInherit(aPrincipalToInherit),
@ -890,7 +905,8 @@ LoadInfo::LoadInfo(
mAllowDeprecatedSystemRequests(aAllowDeprecatedSystemRequests),
mParserCreatedScript(aParserCreatedScript),
mHasStoragePermission(aHasStoragePermission),
mIsFromProcessingFrameAttributes(false) {
mIsFromProcessingFrameAttributes(false),
mLoadingEmbedderPolicy(aLoadingEmbedderPolicy) {
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
MOZ_ASSERT(mLoadingPrincipal ||
aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
@ -1962,6 +1978,20 @@ LoadInfo::GetInternalContentPolicyType(nsContentPolicyType* aResult) {
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetLoadingEmbedderPolicy(
nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) {
*aOutPolicy = mLoadingEmbedderPolicy;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetLoadingEmbedderPolicy(
nsILoadInfo::CrossOriginEmbedderPolicy aPolicy) {
mLoadingEmbedderPolicy = aPolicy;
return NS_OK;
}
already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCsp() {
// Before querying the CSP from the client we have to check if the
// triggeringPrincipal originates from an addon and potentially

Просмотреть файл

@ -173,7 +173,8 @@ class LoadInfo final : public nsILoadInfo {
uint32_t aHttpsOnlyStatus, bool aHasValidUserGestureActivation,
bool aAllowDeprecatedSystemRequests, bool aParserCreatedScript,
bool aHasStoragePermission, uint32_t aRequestBlockingReason,
nsINode* aLoadingContext);
nsINode* aLoadingContext,
nsILoadInfo::CrossOriginEmbedderPolicy aLoadingEmbedderPolicy);
LoadInfo(const LoadInfo& rhs);
NS_IMETHOD GetRedirects(JSContext* aCx,
@ -280,6 +281,12 @@ class LoadInfo final : public nsILoadInfo {
// browsing context container.
// See nsILoadInfo.isFromProcessingFrameAttributes
bool mIsFromProcessingFrameAttributes;
// The cross origin embedder policy that the loading need to respect.
// If the value is nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP, CORP checking
// must be performed for the loading.
// See https://wicg.github.io/cross-origin-embedder-policy/#corp-check.
nsILoadInfo::CrossOriginEmbedderPolicy mLoadingEmbedderPolicy;
};
} // namespace net

Просмотреть файл

@ -658,5 +658,17 @@ TRRLoadInfo::SetParserCreatedScript(bool aParserCreatedScript) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::GetLoadingEmbedderPolicy(
nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::SetLoadingEmbedderPolicy(
nsILoadInfo::CrossOriginEmbedderPolicy aPolicy) {
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -1315,4 +1315,14 @@ interface nsILoadInfo : nsISupports
EMBEDDER_POLICY_NULL = 0,
EMBEDDER_POLICY_REQUIRE_CORP = 1,
};
/**
* This attribute is the loading context's cross origin embedder policy.
* The value is initialized with corresponding WindowContext which get by
* innerWindowIID in the nsILoadInfo.
* It also could be set by workers when fetch is called under
* the workers' scope.
*/
[infallible] attribute nsILoadInfo_CrossOriginEmbedderPolicy
loadingEmbedderPolicy;
};

Просмотреть файл

@ -23,6 +23,7 @@ using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
using refcounted class nsIPropertyBag2 from "mozilla/dom/PropertyBagUtils.h";
using refcounted class nsDOMNavigationTiming from "nsDOMNavigationTiming.h";
using nsILoadInfo::CrossOriginEmbedderPolicy from "nsILoadInfo.h";
namespace mozilla {
namespace net {
@ -156,6 +157,7 @@ struct LoadInfoArgs
uint32_t requestBlockingReason;
CSPInfo? cspToInheritInfo;
bool hasStoragePermission;
CrossOriginEmbedderPolicy loadingEmbedderPolicy;
};
/**

Просмотреть файл

@ -7605,12 +7605,10 @@ nsresult nsHttpChannel::ProcessCrossOriginEmbedderPolicyHeader() {
}
// https://mikewest.github.io/corpp/#abstract-opdef-process-navigation-response
RefPtr<WindowContext> ctx =
WindowContext::GetById(mLoadInfo->GetInnerWindowID());
if (ctx &&
mLoadInfo->GetExternalContentPolicyType() ==
if (mLoadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_SUBDOCUMENT &&
ctx->GetEmbedderPolicy() != nsILoadInfo::EMBEDDER_POLICY_NULL &&
mLoadInfo->GetLoadingEmbedderPolicy() !=
nsILoadInfo::EMBEDDER_POLICY_NULL &&
resultPolicy != nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
return NS_ERROR_BLOCKED_BY_POLICY;
}
@ -7648,13 +7646,10 @@ nsresult nsHttpChannel::ProcessCrossOriginResourcePolicyHeader() {
// 3.2.1.6 If policy is null, and embedder policy is "require-corp", set
// policy to "same-origin".
if (StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
RefPtr<WindowContext> ctx =
WindowContext::GetById(mLoadInfo->GetInnerWindowID());
// Note that we treat invalid value as "cross-origin", which spec
// indicates. We might want to make that stricter.
if (content.IsEmpty() && ctx &&
ctx->GetEmbedderPolicy() == nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
if (content.IsEmpty() && mLoadInfo->GetLoadingEmbedderPolicy() ==
nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
content = NS_LITERAL_CSTRING("same-origin");
}
}

Просмотреть файл

@ -1,13 +0,0 @@
[dedicated-worker.https.html]
[COEP: require-corp module worker in COEP: none frame]
expected: FAIL
[COEP: require-corp worker in COEP: none frame]
expected: FAIL
[COEP: require-corp worker in COEP: require-corp frame]
expected: FAIL
[COEP: require-corp module worker in COEP: require-corp frame]
expected: FAIL