Bug 1890748 - Move responsibility of FeaturePolicy initialization to nsILoadInfo. r=freddyb,necko-reviewers,jesup,dom-core,sefeng

Differential Revision: https://phabricator.services.mozilla.com/D207140
This commit is contained in:
Andreas Farre 2024-05-24 14:28:47 +00:00
parent 2ea7429590
commit 031a90d97c
27 changed files with 220 additions and 165 deletions

View file

@ -2778,12 +2778,8 @@ void CanonicalBrowsingContext::CancelSessionStoreUpdate() {
}
void CanonicalBrowsingContext::SetContainerFeaturePolicy(
FeaturePolicy* aContainerFeaturePolicy) {
mContainerFeaturePolicy = aContainerFeaturePolicy;
if (WindowGlobalParent* current = GetCurrentWindowGlobal()) {
Unused << current->SendSetContainerFeaturePolicy(mContainerFeaturePolicy);
}
Maybe<FeaturePolicyInfo>&& aContainerFeaturePolicyInfo) {
mContainerFeaturePolicyInfo = std::move(aContainerFeaturePolicyInfo);
}
void CanonicalBrowsingContext::SetCrossGroupOpenerId(uint64_t aOpenerId) {
@ -3201,15 +3197,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CanonicalBrowsingContext,
if (tmp->mSessionHistory) {
tmp->mSessionHistory->SetBrowsingContext(nullptr);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionHistory, mContainerFeaturePolicy,
mCurrentBrowserParent, mWebProgress,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionHistory, mCurrentBrowserParent,
mWebProgress,
mSessionStoreSessionStorageUpdateTimer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CanonicalBrowsingContext,
BrowsingContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionHistory, mContainerFeaturePolicy,
mCurrentBrowserParent, mWebProgress,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionHistory, mCurrentBrowserParent,
mWebProgress,
mSessionStoreSessionStorageUpdateTimer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

View file

@ -10,6 +10,7 @@
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/MediaControlKeySource.h"
#include "mozilla/dom/BrowsingContextWebProgress.h"
#include "mozilla/dom/FeaturePolicy.h"
#include "mozilla/dom/ProcessIsolation.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/SessionHistoryEntry.h"
@ -314,9 +315,10 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void ResetScalingZoom();
void SetContainerFeaturePolicy(FeaturePolicy* aContainerFeaturePolicy);
FeaturePolicy* GetContainerFeaturePolicy() const {
return mContainerFeaturePolicy;
void SetContainerFeaturePolicy(
Maybe<FeaturePolicyInfo>&& aContainerFeaturePolicyInfo);
const Maybe<FeaturePolicyInfo>& GetContainerFeaturePolicy() const {
return mContainerFeaturePolicyInfo;
}
void SetRestoreData(SessionStoreRestoreData* aData, ErrorResult& aError);
@ -581,7 +583,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
nsCOMPtr<nsIWebProgressListener> mDocShellProgressBridge;
RefPtr<nsBrowserStatusFilter> mStatusFilter;
RefPtr<FeaturePolicy> mContainerFeaturePolicy;
Maybe<FeaturePolicyInfo> mContainerFeaturePolicyInfo;
friend class BrowserSessionStore;
WeakPtr<SessionStoreFormData>& GetSessionStoreFormDataRef() {

View file

@ -6572,8 +6572,6 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
// after being set here.
blankDoc->SetSandboxFlags(sandboxFlags);
blankDoc->InitFeaturePolicy();
// create a content viewer for us and the new document
docFactory->CreateInstanceForDocument(
NS_ISUPPORTS_CAST(nsIDocShell*, this), blankDoc, "view",
@ -6591,6 +6589,12 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
/* aLocationFlags */ 0);
rv = mIsBeingDestroyed ? NS_ERROR_NOT_AVAILABLE : NS_OK;
}
if (Element* embedderElement = blankDoc->GetEmbedderElement()) {
blankDoc->InitFeaturePolicy(AsVariant(embedderElement));
} else {
blankDoc->InitFeaturePolicy(AsVariant(Nothing{}));
}
}
}

View file

@ -180,6 +180,7 @@
#include "mozilla/dom/HTMLBodyElement.h"
#include "mozilla/dom/HTMLCollectionBinding.h"
#include "mozilla/dom/HTMLDialogElement.h"
#include "mozilla/dom/HTMLEmbedElement.h"
#include "mozilla/dom/HTMLFormElement.h"
#include "mozilla/dom/HTMLIFrameElement.h"
#include "mozilla/dom/HTMLImageElement.h"
@ -187,6 +188,7 @@
#include "mozilla/dom/HTMLLinkElement.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLMetaElement.h"
#include "mozilla/dom/HTMLObjectElement.h"
#include "mozilla/dom/HTMLSharedElement.h"
#include "mozilla/dom/HTMLTextAreaElement.h"
#include "mozilla/dom/ImageTracker.h"
@ -3877,74 +3879,68 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
return NS_OK;
}
static Document* GetInProcessParentDocumentFrom(BrowsingContext* aContext) {
BrowsingContext* parentContext = aContext->GetParent();
if (!parentContext) {
static FeaturePolicy* GetFeaturePolicyFromElement(Element* aElement) {
if (auto* iframe = HTMLIFrameElement::FromNodeOrNull(aElement)) {
return iframe->FeaturePolicy();
}
if (!HTMLObjectElement::FromNodeOrNull(aElement) &&
!HTMLEmbedElement::FromNodeOrNull(aElement)) {
return nullptr;
}
WindowContext* windowContext = parentContext->GetCurrentWindowContext();
if (!windowContext) {
return nullptr;
}
return windowContext->GetDocument();
return aElement->OwnerDoc()->FeaturePolicy();
}
already_AddRefed<dom::FeaturePolicy> Document::GetParentFeaturePolicy() {
BrowsingContext* browsingContext = GetBrowsingContext();
if (!browsingContext) {
return nullptr;
}
if (!browsingContext->IsContentSubframe()) {
return nullptr;
}
HTMLIFrameElement* iframe =
HTMLIFrameElement::FromNodeOrNull(browsingContext->GetEmbedderElement());
if (iframe) {
return do_AddRef(iframe->FeaturePolicy());
}
if (XRE_IsParentProcess()) {
return do_AddRef(browsingContext->Canonical()->GetContainerFeaturePolicy());
}
if (Document* parentDocument =
GetInProcessParentDocumentFrom(browsingContext)) {
return do_AddRef(parentDocument->FeaturePolicy());
}
WindowContext* windowContext = browsingContext->GetCurrentWindowContext();
if (!windowContext) {
return nullptr;
}
WindowGlobalChild* child = windowContext->GetWindowGlobalChild();
if (!child) {
return nullptr;
}
return do_AddRef(child->GetContainerFeaturePolicy());
}
void Document::InitFeaturePolicy() {
void Document::InitFeaturePolicy(
const Variant<Nothing, FeaturePolicyInfo, Element*>&
aContainerFeaturePolicy) {
MOZ_ASSERT(mFeaturePolicy, "we should have FeaturePolicy created");
mFeaturePolicy->ResetDeclaredPolicy();
mFeaturePolicy->SetDefaultOrigin(NodePrincipal());
RefPtr<mozilla::dom::FeaturePolicy> parentPolicy = GetParentFeaturePolicy();
if (parentPolicy) {
// Let's inherit the policy from the parent HTMLIFrameElement if it exists.
mFeaturePolicy->InheritPolicy(parentPolicy);
mFeaturePolicy->SetSrcOrigin(parentPolicy->GetSrcOrigin());
aContainerFeaturePolicy.match(
[](const Nothing&) {},
[this](const FeaturePolicyInfo& aContainerFeaturePolicy) {
// Let's inherit the policy from the possibly cross-origin container.
mFeaturePolicy->InheritPolicy(aContainerFeaturePolicy);
mFeaturePolicy->SetSrcOrigin(aContainerFeaturePolicy.mSrcOrigin);
},
[this](Element* aContainer) {
// Let's inherit the policy from the parent container element if it
// exists.
if (RefPtr<dom::FeaturePolicy> containerFeaturePolicy =
GetFeaturePolicyFromElement(aContainer)) {
mFeaturePolicy->InheritPolicy(containerFeaturePolicy);
mFeaturePolicy->SetSrcOrigin(containerFeaturePolicy->GetSrcOrigin());
}
});
}
Element* GetEmbedderElementFrom(BrowsingContext* aBrowsingContext) {
if (!aBrowsingContext) {
return nullptr;
}
if (!aBrowsingContext->IsContentSubframe()) {
return nullptr;
}
return aBrowsingContext->GetEmbedderElement();
}
nsresult Document::InitFeaturePolicy(nsIChannel* aChannel) {
InitFeaturePolicy();
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
if (Maybe<FeaturePolicyInfo> featurePolicyContainer =
loadInfo->GetContainerFeaturePolicyInfo()) {
InitFeaturePolicy(AsVariant(*featurePolicyContainer));
} else if (Element* embedderElement =
GetEmbedderElementFrom(GetBrowsingContext())) {
InitFeaturePolicy(AsVariant(embedderElement));
} else {
InitFeaturePolicy(AsVariant(Nothing{}));
}
// We don't want to parse the http Feature-Policy header if this pref is off.
if (!StaticPrefs::dom_security_featurePolicy_header_enabled()) {

View file

@ -1503,7 +1503,8 @@ class Document : public nsINode,
void DoNotifyPossibleTitleChange();
void InitFeaturePolicy();
void InitFeaturePolicy(const Variant<Nothing, FeaturePolicyInfo, Element*>&
aContainerFeaturePolicy);
nsresult InitFeaturePolicy(nsIChannel* aChannel);
void EnsureNotEnteringAndExitFullscreen();

View file

@ -1838,7 +1838,8 @@ void nsObjectLoadingContent::MaybeStoreCrossOriginFeaturePolicy() {
FeaturePolicy* featurePolicy = el->OwnerDoc()->FeaturePolicy();
if (ContentChild* cc = ContentChild::GetSingleton()) {
Unused << cc->SendSetContainerFeaturePolicy(browsingContext, featurePolicy);
if (ContentChild* cc = ContentChild::GetSingleton(); cc && featurePolicy) {
Unused << cc->SendSetContainerFeaturePolicy(
browsingContext, Some(featurePolicy->ToFeaturePolicyInfo()));
}
}

View file

@ -255,8 +255,8 @@ void HTMLIFrameElement::MaybeStoreCrossOriginFeaturePolicy() {
}
if (ContentChild* cc = ContentChild::GetSingleton()) {
Unused << cc->SendSetContainerFeaturePolicy(browsingContext,
mFeaturePolicy);
Unused << cc->SendSetContainerFeaturePolicy(
browsingContext, Some(mFeaturePolicy->ToFeaturePolicyInfo()));
}
}

View file

@ -8198,13 +8198,13 @@ IPCResult ContentParent::RecvFOGData(ByteBuf&& buf) {
mozilla::ipc::IPCResult ContentParent::RecvSetContainerFeaturePolicy(
const MaybeDiscardedBrowsingContext& aContainerContext,
FeaturePolicy* aContainerFeaturePolicy) {
MaybeFeaturePolicyInfo&& aContainerFeaturePolicyInfo) {
if (aContainerContext.IsNullOrDiscarded()) {
return IPC_OK();
}
auto* context = aContainerContext.get_canonical();
context->SetContainerFeaturePolicy(aContainerFeaturePolicy);
context->SetContainerFeaturePolicy(std::move(aContainerFeaturePolicyInfo));
return IPC_OK();
}

View file

@ -1379,7 +1379,7 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvSetContainerFeaturePolicy(
const MaybeDiscardedBrowsingContext& aContainerContext,
FeaturePolicy* aContainerFeaturePolicy);
MaybeFeaturePolicyInfo&& aContainerFeaturePolicyInfo);
mozilla::ipc::IPCResult RecvGetSystemIcon(nsIURI* aURI,
GetSystemIconResolver&& aResolver);

View file

@ -132,16 +132,6 @@ struct FrameScriptInfo
bool runInGlobalScope;
};
struct FeaturePolicyInfo
{
nsString[] inheritedDeniedFeatureNames;
nsString[] attributeEnabledFeatureNames;
nsString declaredString;
nullable nsIPrincipal defaultOrigin;
nullable nsIPrincipal selfOrigin;
nullable nsIPrincipal srcOrigin;
};
/**
* The information required to complete a window creation request.
*/

View file

@ -154,7 +154,7 @@ using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHi
using mozilla::media::MediaCodecsSupported from "MediaCodecsSupport.h";
using mozilla::RemoteDecodeIn from "mozilla/RemoteDecoderManagerChild.h";
using mozilla::dom::PerformanceTimingData from "mozilla/dom/PerformanceTiming.h";
[RefCounted] using mozilla::dom::FeaturePolicy from "mozilla/dom/FeaturePolicy.h";
using mozilla::dom::MaybeFeaturePolicyInfo from "mozilla/dom/FeaturePolicy.h";
using mozilla::dom::Wireframe from "mozilla/dom/DocumentBinding.h";
using mozilla::PerfStats::MetricMask from "mozilla/PerfStats.h";
[RefCounted] using class nsIX509Cert from "nsIX509Cert.h";
@ -1955,7 +1955,7 @@ child:
parent:
async SetContainerFeaturePolicy(MaybeDiscardedBrowsingContext aContainerContext,
nullable FeaturePolicy aContainerFeaturePolicy);
MaybeFeaturePolicyInfo aContainerFeaturePolicyInfo);
// Obtain an icon from the system widget toolkit, in nsIconDecoder
// format. Not supported (or needed) on all platforms; see the

View file

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include "mozilla/dom/DocShellMessageUtils.h";
include "mozilla/dom/FeaturePolicyUtils.h";
include "mozilla/dom/IdentityCredentialSerializationHelpers.h";
include "mozilla/dom/PermissionMessageUtils.h";
include "mozilla/dom/SessionStoreMessageUtils.h";
@ -34,7 +33,6 @@ using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
[RefCounted] using class nsITransportSecurityInfo from "nsITransportSecurityInfo.h";
using mozilla::UseCounters from "mozilla/UseCounter.h";
using mozilla::dom::MaybeDiscardedWindowContext from "mozilla/dom/WindowContext.h";
[RefCounted] using mozilla::dom::FeaturePolicy from "mozilla/dom/FeaturePolicy.h";
[RefCounted] using mozilla::dom::SessionStoreRestoreData from "mozilla/dom/SessionStoreRestoreData.h";
using mozilla::dom::IdentityCredentialRequestOptions from "mozilla/dom/IdentityCredentialBinding.h";
@ -88,8 +86,6 @@ child:
*/
async ResetScalingZoom();
async SetContainerFeaturePolicy(nullable FeaturePolicy aContainerFeaturePolicy);
async RestoreDocShellState(DocShellRestoreState aState)
returns (bool success);

View file

@ -513,12 +513,6 @@ mozilla::ipc::IPCResult WindowGlobalChild::RecvResetScalingZoom() {
return IPC_OK();
}
mozilla::ipc::IPCResult WindowGlobalChild::RecvSetContainerFeaturePolicy(
dom::FeaturePolicy* aContainerFeaturePolicy) {
mContainerFeaturePolicy = aContainerFeaturePolicy;
return IPC_OK();
}
mozilla::ipc::IPCResult WindowGlobalChild::RecvRestoreDocShellState(
const dom::sessionstore::DocShellRestoreState& aState,
RestoreDocShellStateResolver&& aResolve) {

View file

@ -21,7 +21,6 @@ class nsDocShell;
namespace mozilla::dom {
class BrowsingContext;
class FeaturePolicy;
class WindowContext;
class WindowGlobalParent;
class JSWindowActorChild;
@ -144,10 +143,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
dom::FeaturePolicy* GetContainerFeaturePolicy() const {
return mContainerFeaturePolicy;
}
void UnblockBFCacheFor(BFCacheStatus aStatus);
void BlockBFCacheFor(BFCacheStatus aStatus);
@ -189,9 +184,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
mozilla::ipc::IPCResult RecvResetScalingZoom();
mozilla::ipc::IPCResult RecvSetContainerFeaturePolicy(
dom::FeaturePolicy* aContainerFeaturePolicy);
mozilla::ipc::IPCResult RecvRestoreDocShellState(
const dom::sessionstore::DocShellRestoreState& aState,
RestoreDocShellStateResolver&& aResolve);

View file

@ -178,9 +178,6 @@ void WindowGlobalParent::Init() {
if (!BrowsingContext()->IsDiscarded()) {
MOZ_ALWAYS_SUCCEEDS(
BrowsingContext()->SetCurrentInnerWindowId(InnerWindowId()));
Unused << SendSetContainerFeaturePolicy(
BrowsingContext()->GetContainerFeaturePolicy());
}
if (BrowsingContext()->IsTopContent()) {

View file

@ -6,10 +6,12 @@
#include "FeaturePolicy.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Feature.h"
#include "mozilla/dom/FeaturePolicyBinding.h"
#include "mozilla/dom/FeaturePolicyParser.h"
#include "mozilla/dom/FeaturePolicyUtils.h"
#include "mozilla/dom/HTMLIFrameElement.h"
#include "mozilla/StaticPrefs_dom.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"
@ -69,6 +71,30 @@ void FeaturePolicy::InheritPolicy(FeaturePolicy* aParentPolicy) {
});
}
void FeaturePolicy::InheritPolicy(
const FeaturePolicyInfo& aContainerFeaturePolicyInfo) {
// We create a temporary FeaturePolicy from the FeaturePolicyInfo to be able
// to re-use the inheriting functionality from FeaturePolicy.
RefPtr<dom::FeaturePolicy> featurePolicy = new dom::FeaturePolicy(nullptr);
featurePolicy->SetDefaultOrigin(aContainerFeaturePolicyInfo.mDefaultOrigin);
featurePolicy->SetInheritedDeniedFeatureNames(
aContainerFeaturePolicyInfo.mInheritedDeniedFeatureNames);
const auto& declaredString = aContainerFeaturePolicyInfo.mDeclaredString;
if (aContainerFeaturePolicyInfo.mSelfOrigin && !declaredString.IsEmpty()) {
featurePolicy->SetDeclaredPolicy(nullptr, declaredString,
aContainerFeaturePolicyInfo.mSelfOrigin,
aContainerFeaturePolicyInfo.mSrcOrigin);
}
for (const auto& featureName :
aContainerFeaturePolicyInfo.mAttributeEnabledFeatureNames) {
featurePolicy->MaybeSetAllowedPolicy(featureName);
}
InheritPolicy(featurePolicy);
}
void FeaturePolicy::SetInheritedDeniedFeature(const nsAString& aFeatureName) {
MOZ_ASSERT(!HasInheritedDeniedFeature(aFeatureName));
mInheritedDeniedFeatureNames.AppendElement(aFeatureName);
@ -331,4 +357,13 @@ void FeaturePolicy::MaybeSetAllowedPolicy(const nsAString& aFeatureName) {
mAttributeEnabledFeatureNames.AppendElement(aFeatureName);
}
FeaturePolicyInfo FeaturePolicy::ToFeaturePolicyInfo() const {
return {mInheritedDeniedFeatureNames.Clone(),
mAttributeEnabledFeatureNames.Clone(),
mDeclaredString,
mDefaultOrigin,
mSelfOrigin,
mSrcOrigin};
}
} // namespace mozilla::dom

View file

@ -56,12 +56,24 @@ class nsINode;
namespace mozilla::dom {
class Document;
class BrowsingContext;
class Feature;
template <typename T>
class Optional;
class FeaturePolicyUtils;
struct FeaturePolicyInfo final {
CopyableTArray<nsString> mInheritedDeniedFeatureNames;
CopyableTArray<nsString> mAttributeEnabledFeatureNames;
nsString mDeclaredString;
nsCOMPtr<nsIPrincipal> mDefaultOrigin;
nsCOMPtr<nsIPrincipal> mSelfOrigin;
nsCOMPtr<nsIPrincipal> mSrcOrigin;
};
using MaybeFeaturePolicyInfo = Maybe<FeaturePolicyInfo>;
class FeaturePolicy final : public nsISupports, public nsWrapperCache {
friend class FeaturePolicyUtils;
@ -85,6 +97,9 @@ class FeaturePolicy final : public nsISupports, public nsWrapperCache {
// Inherits the policy from the 'parent' context if it exists.
void InheritPolicy(FeaturePolicy* aParentFeaturePolicy);
// Inherits the policy from the 'parent' context if it exists.
void InheritPolicy(const FeaturePolicyInfo& aContainerFeaturePolicyInfo);
// Sets the declarative part of the policy. This can be from the HTTP header
// or for the 'allow' HTML attribute.
void SetDeclaredPolicy(mozilla::dom::Document* aDocument,
@ -154,6 +169,8 @@ class FeaturePolicy final : public nsISupports, public nsWrapperCache {
nsIPrincipal* GetSelfOrigin() const { return mSelfOrigin; }
nsIPrincipal* GetSrcOrigin() const { return mSrcOrigin; }
FeaturePolicyInfo ToFeaturePolicyInfo() const;
private:
~FeaturePolicy() = default;

View file

@ -7,8 +7,9 @@
#include "FeaturePolicyUtils.h"
#include "nsIOService.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/ipc/IPDLParamTraits.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/FeaturePolicyViolationReportBody.h"
#include "mozilla/dom/ReportingUtils.h"
#include "mozilla/StaticPrefs_dom.h"
@ -248,66 +249,46 @@ void FeaturePolicyUtils::ReportViolation(Document* aDocument,
} // namespace dom
namespace ipc {
void IPDLParamTraits<dom::FeaturePolicy*>::Write(IPC::MessageWriter* aWriter,
IProtocol* aActor,
dom::FeaturePolicy* aParam) {
if (!aParam) {
WriteIPDLParam(aWriter, aActor, false);
return;
}
WriteIPDLParam(aWriter, aActor, true);
dom::FeaturePolicyInfo info;
info.defaultOrigin() = aParam->DefaultOrigin();
info.selfOrigin() = aParam->GetSelfOrigin();
info.srcOrigin() = aParam->GetSrcOrigin();
info.declaredString() = aParam->DeclaredString();
info.inheritedDeniedFeatureNames() =
aParam->InheritedDeniedFeatureNames().Clone();
info.attributeEnabledFeatureNames() =
aParam->AttributeEnabledFeatureNames().Clone();
WriteIPDLParam(aWriter, aActor, info);
void IPDLParamTraits<dom::FeaturePolicyInfo>::Write(
IPC::MessageWriter* aWriter, IProtocol* aActor,
const dom::FeaturePolicyInfo& aParam) {
WriteIPDLParam(aWriter, aActor, aParam.mInheritedDeniedFeatureNames);
WriteIPDLParam(aWriter, aActor, aParam.mAttributeEnabledFeatureNames);
WriteIPDLParam(aWriter, aActor, aParam.mDeclaredString);
WriteIPDLParam(aWriter, aActor, aParam.mDefaultOrigin);
WriteIPDLParam(aWriter, aActor, aParam.mSelfOrigin);
WriteIPDLParam(aWriter, aActor, aParam.mSrcOrigin);
}
bool IPDLParamTraits<dom::FeaturePolicy*>::Read(
bool IPDLParamTraits<dom::FeaturePolicyInfo>::Read(
IPC::MessageReader* aReader, IProtocol* aActor,
RefPtr<dom::FeaturePolicy>* aResult) {
*aResult = nullptr;
bool notnull = false;
if (!ReadIPDLParam(aReader, aActor, &notnull)) {
dom::FeaturePolicyInfo* aResult) {
if (!ReadIPDLParam(aReader, aActor, &aResult->mInheritedDeniedFeatureNames)) {
return false;
}
if (!notnull) {
return true;
}
dom::FeaturePolicyInfo info;
if (!ReadIPDLParam(aReader, aActor, &info)) {
if (!ReadIPDLParam(aReader, aActor,
&aResult->mAttributeEnabledFeatureNames)) {
return false;
}
// Note that we only do IPC for feature policy to inherit policy from parent
// to child document. That does not need to bind feature policy with a node.
RefPtr<dom::FeaturePolicy> featurePolicy = new dom::FeaturePolicy(nullptr);
featurePolicy->SetDefaultOrigin(info.defaultOrigin());
featurePolicy->SetInheritedDeniedFeatureNames(
info.inheritedDeniedFeatureNames());
const auto& declaredString = info.declaredString();
if (info.selfOrigin() && !declaredString.IsEmpty()) {
featurePolicy->SetDeclaredPolicy(nullptr, declaredString, info.selfOrigin(),
info.srcOrigin());
if (!ReadIPDLParam(aReader, aActor, &aResult->mDeclaredString)) {
return false;
}
for (auto& featureName : info.attributeEnabledFeatureNames()) {
featurePolicy->MaybeSetAllowedPolicy(featureName);
if (!ReadIPDLParam(aReader, aActor, &aResult->mDefaultOrigin)) {
return false;
}
if (!ReadIPDLParam(aReader, aActor, &aResult->mSelfOrigin)) {
return false;
}
if (!ReadIPDLParam(aReader, aActor, &aResult->mSrcOrigin)) {
return false;
}
*aResult = std::move(featurePolicy);
return true;
}
} // namespace ipc

View file

@ -7,7 +7,6 @@
#ifndef mozilla_dom_FeaturePolicyUtils_h
#define mozilla_dom_FeaturePolicyUtils_h
#include "nsString.h"
#include <functional>
#include "mozilla/dom/FeaturePolicy.h"
@ -79,12 +78,13 @@ template <typename T>
struct IPDLParamTraits;
template <>
struct IPDLParamTraits<mozilla::dom::FeaturePolicy*> {
struct IPDLParamTraits<dom::FeaturePolicyInfo> {
static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
mozilla::dom::FeaturePolicy* aParam);
const mozilla::dom::FeaturePolicyInfo& aParam);
static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
RefPtr<mozilla::dom::FeaturePolicy>* aResult);
dom::FeaturePolicyInfo* aResult);
};
} // namespace ipc
} // namespace mozilla

View file

@ -6,6 +6,7 @@
#include "txMozillaXMLOutput.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/FeaturePolicy.h"
#include "nsIDocShell.h"
#include "nsIScriptElement.h"
#include "nsCharsetSource.h"

View file

@ -962,10 +962,11 @@ void LoadInfoToParentLoadInfoForwarder(
aLoadInfo->GetServiceWorkerTaintingSynthesized(),
aLoadInfo->GetDocumentHasUserInteracted(),
aLoadInfo->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(),
cookieJarSettingsArgs, aLoadInfo->GetRequestBlockingReason(),
aLoadInfo->GetStoragePermission(), overriddenFingerprintingSettingsArg,
aLoadInfo->GetIsMetaRefresh(), isThirdPartyContextToTopWindow,
aLoadInfo->GetIsInThirdPartyContext(), unstrippedURI);
cookieJarSettingsArgs, aLoadInfo->GetContainerFeaturePolicyInfo(),
aLoadInfo->GetRequestBlockingReason(), aLoadInfo->GetStoragePermission(),
overriddenFingerprintingSettingsArg, aLoadInfo->GetIsMetaRefresh(),
isThirdPartyContextToTopWindow, aLoadInfo->GetIsInThirdPartyContext(),
unstrippedURI);
}
nsresult MergeParentLoadInfoForwarder(
@ -1071,6 +1072,11 @@ nsresult MergeParentLoadInfoForwarder(
rv = aLoadInfo->SetUnstrippedURI(aForwarderArgs.unstrippedURI());
NS_ENSURE_SUCCESS(rv, rv);
if (aForwarderArgs.containerFeaturePolicyInfo()) {
aLoadInfo->SetContainerFeaturePolicyInfo(
*aForwarderArgs.containerFeaturePolicyInfo());
}
return NS_OK;
}

View file

@ -14,6 +14,7 @@
#include "mozilla/dom/ClientIPCTypes.h"
#include "mozilla/dom/ClientSource.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceStorage.h"
#include "mozilla/dom/BrowserChild.h"
@ -606,6 +607,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mChannelCreationOriginalURI(rhs.mChannelCreationOriginalURI),
mCookieJarSettings(rhs.mCookieJarSettings),
mCspToInherit(rhs.mCspToInherit),
mContainerFeaturePolicyInfo(rhs.mContainerFeaturePolicyInfo),
mTriggeringRemoteType(rhs.mTriggeringRemoteType),
mSandboxedNullPrincipalID(rhs.mSandboxedNullPrincipalID),
mClientInfo(rhs.mClientInfo),
@ -2371,6 +2373,15 @@ already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCspToInherit() {
return cspToInherit.forget();
}
Maybe<FeaturePolicyInfo> LoadInfo::GetContainerFeaturePolicyInfo() {
return mContainerFeaturePolicyInfo;
}
void LoadInfo::SetContainerFeaturePolicyInfo(
const FeaturePolicyInfo& aContainerFeaturePolicyInfo) {
mContainerFeaturePolicyInfo = Some(aContainerFeaturePolicyInfo);
}
nsIInterceptionInfo* LoadInfo::InterceptionInfo() { return mInterceptionInfo; }
void LoadInfo::SetInterceptionInfo(nsIInterceptionInfo* aInfo) {

View file

@ -7,6 +7,7 @@
#ifndef mozilla_LoadInfo_h
#define mozilla_LoadInfo_h
#include "mozilla/dom/FeaturePolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIInterceptionInfo.h"
#include "nsILoadInfo.h"
@ -195,6 +196,11 @@ class LoadInfo final : public nsILoadInfo {
mIsThirdPartyContextToTopWindow.reset();
}
void SetContinerFeaturePolicy(
const Maybe<dom::FeaturePolicyInfo>& aContainerFeaturePolicy) {
mContainerFeaturePolicyInfo = aContainerFeaturePolicy;
}
#ifdef DEBUG
void MarkOverriddenFingerprintingSettingsAsSet() {
mOverriddenFingerprintingSettingsIsSet = true;
@ -299,6 +305,7 @@ class LoadInfo final : public nsILoadInfo {
nsCOMPtr<nsICSPEventListener> mCSPEventListener;
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
nsCOMPtr<nsIContentSecurityPolicy> mCspToInherit;
Maybe<dom::FeaturePolicyInfo> mContainerFeaturePolicyInfo;
nsCString mTriggeringRemoteType;
nsID mSandboxedNullPrincipalID;

View file

@ -6,6 +6,8 @@
#include "TRRLoadInfo.h"
#include "mozilla/dom/ClientSource.h"
#include "mozilla/dom/FeaturePolicy.h"
#include "mozilla/dom/DOMTypes.h"
#include "nsContentUtils.h"
#include "nsIRedirectHistoryEntry.h"
@ -724,6 +726,13 @@ already_AddRefed<nsIContentSecurityPolicy> TRRLoadInfo::GetCspToInherit() {
return nullptr;
}
Maybe<FeaturePolicyInfo> TRRLoadInfo::GetContainerFeaturePolicyInfo() {
return Nothing();
}
void TRRLoadInfo::SetContainerFeaturePolicyInfo(
const FeaturePolicyInfo& aContainerFeaturePolicyInfo) {}
NS_IMETHODIMP
TRRLoadInfo::GetHttpsOnlyStatus(uint32_t* aHttpsOnlyStatus) {
return NS_ERROR_NOT_IMPLEMENTED;

View file

@ -32,6 +32,7 @@ namespace mozilla {
namespace dom {
class ClientInfo;
class ClientSource;
struct FeaturePolicyInfo;
class PerformanceStorage;
class ServiceWorkerDescriptor;
} // namespace dom
@ -56,6 +57,8 @@ native OriginAttributes(mozilla::OriginAttributes);
[ptr] native PerformanceStoragePtr(mozilla::dom::PerformanceStorage);
native LoadTainting(mozilla::LoadTainting);
native CSPRef(already_AddRefed<nsIContentSecurityPolicy>);
native MaybeFeaturePolicyInfo(mozilla::Maybe<mozilla::dom::FeaturePolicyInfo>);
[ref] native const_FeaturePolicyInfoRef(const mozilla::dom::FeaturePolicyInfo);
typedef unsigned long nsSecurityFlags;
@ -1333,6 +1336,15 @@ interface nsILoadInfo : nsISupports
[notxpcom,nostdcall] CSPRef GetPreloadCsp();
[notxpcom,nostdcall] CSPRef GetCspToInherit();
/**
* The possibly cross-origin container feature policy required to
* initialize the feature policy of a document load.
*/
[noscript, nostdcall, notxpcom]
MaybeFeaturePolicyInfo GetContainerFeaturePolicyInfo();
[noscript, nostdcall, notxpcom]
void SetContainerFeaturePolicyInfo(in const_FeaturePolicyInfoRef aContainerFeaturePolicy);
/**
* The service worker and fetch specifications require returning the
* exact tainting level of the Response passed to FetchEvent.respondWith().

View file

@ -639,6 +639,9 @@ auto DocumentLoadListener::Open(nsDocShellLoadState* aLoadState,
OriginAttributes attrs;
loadingContext->GetOriginAttributes(attrs);
aLoadInfo->SetContinerFeaturePolicy(
loadingContext->GetContainerFeaturePolicy());
mLoadIdentifier = aLoadState->GetLoadIdentifier();
// See description of mFileName in nsDocShellLoadState.h
mIsDownload = !aLoadState->FileName().IsVoid();

View file

@ -15,6 +15,7 @@ include DOMTypes;
include ProtocolTypes;
include "mozilla/dom/FetchIPCTypes.h";
include "mozilla/dom/FeaturePolicyUtils.h";
include "mozilla/dom/PropertyBagUtils.h";
include "mozilla/dom/ReferrerInfoUtils.h";
include "mozilla/ipc/URIUtils.h";
@ -37,6 +38,7 @@ using nsILoadInfo::StoragePermissionState from "nsILoadInfo.h";
using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
using mozilla::dom::RequestMode from "mozilla/dom/RequestBinding.h";
using mozilla::net::LinkHeader from "nsNetUtil.h";
using mozilla::dom::FeaturePolicyInfo from "mozilla/dom/FeaturePolicy.h";
namespace mozilla {
namespace net {
@ -258,6 +260,8 @@ struct ParentLoadInfoForwarderArgs
CookieJarSettingsArgs? cookieJarSettings;
FeaturePolicyInfo? containerFeaturePolicyInfo;
uint32_t requestBlockingReason;
StoragePermissionState storagePermission;