1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/WindowGlobalActor.h"
9 #include "AutoplayPolicy.h"
10 #include "nsContentUtils.h"
11 #include "mozilla/Components.h"
12 #include "mozilla/ContentBlockingAllowList.h"
13 #include "mozilla/Logging.h"
14 #include "mozilla/dom/Document.h"
15 #include "mozilla/dom/JSActorService.h"
16 #include "mozilla/dom/JSWindowActorParent.h"
17 #include "mozilla/dom/JSWindowActorChild.h"
18 #include "mozilla/dom/JSWindowActorProtocol.h"
19 #include "mozilla/dom/PopupBlocker.h"
20 #include "mozilla/net/CookieJarSettings.h"
21 #include "mozilla/dom/WindowContext.h"
22 #include "mozilla/dom/WindowGlobalChild.h"
23 #include "mozilla/dom/WindowGlobalParent.h"
25 #include "nsGlobalWindowInner.h"
26 #include "nsNetUtil.h"
28 namespace mozilla::dom
{
30 // CORPP 3.1.3 https://mikewest.github.io/corpp/#integration-html
31 static nsILoadInfo::CrossOriginEmbedderPolicy
InheritedPolicy(
32 dom::BrowsingContext
* aBrowsingContext
) {
33 WindowContext
* inherit
= aBrowsingContext
->GetParentWindowContext();
35 return inherit
->GetEmbedderPolicy();
38 return nsILoadInfo::EMBEDDER_POLICY_NULL
;
41 // Common WindowGlobalInit creation code used by both `AboutBlankInitializer`
42 // and `WindowInitializer`.
43 WindowGlobalInit
WindowGlobalActor::BaseInitializer(
44 dom::BrowsingContext
* aBrowsingContext
, uint64_t aInnerWindowId
,
45 uint64_t aOuterWindowId
) {
46 MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext
);
48 using Indexes
= WindowContext::FieldIndexes
;
50 WindowGlobalInit init
;
51 auto& ctx
= init
.context();
52 ctx
.mInnerWindowId
= aInnerWindowId
;
53 ctx
.mOuterWindowId
= aOuterWindowId
;
54 ctx
.mBrowsingContextId
= aBrowsingContext
->Id();
56 // If any synced fields need to be initialized from our BrowsingContext, we
57 // can initialize them here.
58 auto& fields
= ctx
.mFields
;
59 fields
.Get
<Indexes::IDX_EmbedderPolicy
>() = InheritedPolicy(aBrowsingContext
);
60 fields
.Get
<Indexes::IDX_AutoplayPermission
>() =
61 nsIPermissionManager::UNKNOWN_ACTION
;
62 fields
.Get
<Indexes::IDX_AllowJavascript
>() = true;
66 WindowGlobalInit
WindowGlobalActor::AboutBlankInitializer(
67 dom::BrowsingContext
* aBrowsingContext
, nsIPrincipal
* aPrincipal
) {
68 WindowGlobalInit init
=
69 BaseInitializer(aBrowsingContext
, nsContentUtils::GenerateWindowId(),
70 nsContentUtils::GenerateWindowId());
72 init
.principal() = aPrincipal
;
73 init
.storagePrincipal() = aPrincipal
;
74 Unused
<< NS_NewURI(getter_AddRefs(init
.documentURI()), "about:blank");
75 init
.isInitialDocument() = true;
80 WindowGlobalInit
WindowGlobalActor::WindowInitializer(
81 nsGlobalWindowInner
* aWindow
) {
82 WindowGlobalInit init
=
83 BaseInitializer(aWindow
->GetBrowsingContext(), aWindow
->WindowID(),
84 aWindow
->GetOuterWindow()->WindowID());
86 init
.principal() = aWindow
->GetPrincipal();
87 init
.storagePrincipal() = aWindow
->GetEffectiveStoragePrincipal();
88 init
.documentURI() = aWindow
->GetDocumentURI();
90 Document
* doc
= aWindow
->GetDocument();
92 init
.isInitialDocument() = doc
->IsInitialDocument();
93 init
.blockAllMixedContent() = doc
->GetBlockAllMixedContent(false);
94 init
.upgradeInsecureRequests() = doc
->GetUpgradeInsecureRequests(false);
95 init
.sandboxFlags() = doc
->GetSandboxFlags();
96 net::CookieJarSettings::Cast(doc
->CookieJarSettings())
97 ->Serialize(init
.cookieJarSettings());
98 init
.httpsOnlyStatus() = doc
->HttpsOnlyStatus();
100 using Indexes
= WindowContext::FieldIndexes
;
102 auto& fields
= init
.context().mFields
;
103 fields
.Get
<Indexes::IDX_CookieBehavior
>() =
104 Some(doc
->CookieJarSettings()->GetCookieBehavior());
105 fields
.Get
<Indexes::IDX_IsOnContentBlockingAllowList
>() =
106 doc
->CookieJarSettings()->GetIsOnContentBlockingAllowList();
107 fields
.Get
<Indexes::IDX_IsThirdPartyWindow
>() = doc
->HasThirdPartyChannel();
108 fields
.Get
<Indexes::IDX_IsThirdPartyTrackingResourceWindow
>() =
109 nsContentUtils::IsThirdPartyTrackingResourceWindow(aWindow
);
110 fields
.Get
<Indexes::IDX_ShouldResistFingerprinting
>() =
111 doc
->ShouldResistFingerprinting(RFPTarget::IsAlwaysEnabledForPrecompute
);
112 fields
.Get
<Indexes::IDX_OverriddenFingerprintingSettings
>() =
113 doc
->GetOverriddenFingerprintingSettings();
114 fields
.Get
<Indexes::IDX_IsSecureContext
>() = aWindow
->IsSecureContext();
116 // Initialze permission fields
117 fields
.Get
<Indexes::IDX_AutoplayPermission
>() =
118 media::AutoplayPolicy::GetSiteAutoplayPermission(init
.principal());
119 fields
.Get
<Indexes::IDX_PopupPermission
>() =
120 PopupBlocker::GetPopupPermission(init
.principal());
122 // Initialize top level permission fields
123 if (aWindow
->GetBrowsingContext()->IsTop()) {
124 fields
.Get
<Indexes::IDX_AllowMixedContent
>() = [&] {
125 uint32_t permit
= nsIPermissionManager::UNKNOWN_ACTION
;
126 nsCOMPtr
<nsIPermissionManager
> permissionManager
=
127 components::PermissionManager::Service();
129 if (permissionManager
) {
130 permissionManager
->TestPermissionFromPrincipal(
131 init
.principal(), "mixed-content"_ns
, &permit
);
134 return permit
== nsIPermissionManager::ALLOW_ACTION
;
137 fields
.Get
<Indexes::IDX_ShortcutsPermission
>() =
138 nsGlobalWindowInner::GetShortcutsPermission(init
.principal());
141 if (auto policy
= doc
->GetEmbedderPolicy()) {
142 fields
.Get
<Indexes::IDX_EmbedderPolicy
>() = *policy
;
145 // Init Mixed Content Fields
146 nsCOMPtr
<nsIURI
> innerDocURI
= NS_GetInnermostURI(doc
->GetDocumentURI());
147 fields
.Get
<Indexes::IDX_IsSecure
>() =
148 innerDocURI
&& innerDocURI
->SchemeIs("https");
150 nsCOMPtr
<nsITransportSecurityInfo
> securityInfo
;
151 if (nsCOMPtr
<nsIChannel
> channel
= doc
->GetChannel()) {
152 nsCOMPtr
<nsILoadInfo
> loadInfo(channel
->LoadInfo());
153 fields
.Get
<Indexes::IDX_IsOriginalFrameSource
>() =
154 loadInfo
->GetOriginalFrameSrcLoad();
155 fields
.Get
<Indexes::IDX_UsingStorageAccess
>() =
156 loadInfo
->GetStoragePermission() != nsILoadInfo::NoStoragePermission
;
158 channel
->GetSecurityInfo(getter_AddRefs(securityInfo
));
160 init
.securityInfo() = securityInfo
;
162 fields
.Get
<Indexes::IDX_IsLocalIP
>() =
163 init
.principal()->GetIsLocalIpAddress();
165 // Most data here is specific to the Document, which can change without
166 // creating a new WindowGlobal. Anything new added here which fits that
167 // description should also be synchronized in
168 // WindowGlobalChild::OnNewDocument.
172 already_AddRefed
<JSActorProtocol
> WindowGlobalActor::MatchingJSActorProtocol(
173 JSActorService
* aActorSvc
, const nsACString
& aName
, ErrorResult
& aRv
) {
174 RefPtr
<JSWindowActorProtocol
> proto
=
175 aActorSvc
->GetJSWindowActorProtocol(aName
);
177 aRv
.ThrowNotFoundError(nsPrintfCString("No such JSWindowActor '%s'",
178 PromiseFlatCString(aName
).get()));
182 if (!proto
->Matches(BrowsingContext(), GetDocumentURI(), GetRemoteType(),
184 MOZ_ASSERT(aRv
.Failed());
187 MOZ_ASSERT(!aRv
.Failed());
188 return proto
.forget();
191 } // namespace mozilla::dom