Bug 1770498: Populate the RFP member of CookieJar Settings r=timhuang,geckoview-reviewers,owlish

CookieJarSettings frequently gets populated in a place
where we have ready access to the Document/Channel it
is being constructed for. This lets us populate the boolean
and pass it into CookieJarSetting's constructor easily.

When it is created for LoadInfo, we need to plumb the URI
through by adding it to LoadInfo::CreateForDocument.

Differential Revision: https://phabricator.services.mozilla.com/D150588
This commit is contained in:
Tom Ritter 2022-07-15 20:39:19 +00:00
Родитель 489d2393ae
Коммит 1c40624193
14 изменённых файлов: 118 добавлений и 54 удалений

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

@ -8495,9 +8495,10 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
// Ideally we should use the same loadinfo as within DoURILoad which
// should match this one when both are applicable.
nsCOMPtr<nsILoadInfo> secCheckLoadInfo = new LoadInfo(
mScriptGlobal, aLoadState->TriggeringPrincipal(), requestingContext,
nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK, 0);
nsCOMPtr<nsILoadInfo> secCheckLoadInfo =
new LoadInfo(mScriptGlobal, aLoadState->URI(),
aLoadState->TriggeringPrincipal(), requestingContext,
nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK, 0);
// Since Content Policy checks are performed within docShell as well as
// the ContentSecurityManager we need a reliable way to let certain
@ -10423,7 +10424,8 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
aLoadState->GetLoadIdentifier());
RefPtr<LoadInfo> loadInfo =
(contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT)
? new LoadInfo(loadingWindow, aLoadState->TriggeringPrincipal(),
? new LoadInfo(loadingWindow, aLoadState->URI(),
aLoadState->TriggeringPrincipal(),
topLevelLoadingContext, securityFlags, sandboxFlags)
: new LoadInfo(loadingPrincipal, aLoadState->TriggeringPrincipal(),
loadingNode, securityFlags, contentPolicyType,

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

@ -17757,7 +17757,9 @@ nsICookieJarSettings* Document::CookieJarSettings() {
inProcessParent->CookieJarSettings()
->GetIsFirstPartyIsolated(),
inProcessParent->CookieJarSettings()
->GetIsOnContentBlockingAllowList())
->GetIsOnContentBlockingAllowList(),
inProcessParent->CookieJarSettings()
->GetShouldResistFingerprinting())
: net::CookieJarSettings::Create(NodePrincipal());
if (auto* wgc = GetWindowGlobalChild()) {

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

@ -4978,7 +4978,10 @@ Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
if (mDoc) {
cookieJarSettings = mDoc->CookieJarSettings();
} else {
cookieJarSettings = net::CookieJarSettings::GetBlockingAll();
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(this->GetExtantDoc());
cookieJarSettings =
net::CookieJarSettings::GetBlockingAll(shouldResistFingerprinting);
}
// Note that this behavior is observable: if we grant storage permission to a

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

@ -234,9 +234,13 @@ ReferrerPolicy ReferrerInfo::GetDefaultReferrerPolicy(nsIHttpChannel* aChannel,
nsCOMPtr<nsICookieJarSettings> cjs;
Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cjs));
if (!cjs) {
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(aChannel);
cjs = aPrivateBrowsing
? net::CookieJarSettings::Create(CookieJarSettings::ePrivate)
: net::CookieJarSettings::Create(CookieJarSettings::eRegular);
? net::CookieJarSettings::Create(CookieJarSettings::ePrivate,
shouldResistFingerprinting)
: net::CookieJarSettings::Create(CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
// We only check if the channel is isolated if it's in the parent process

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

@ -1343,10 +1343,17 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
// current state of the prefs/permissions.
nsCOMPtr<nsICookieJarSettings> cookieJarSettings = aCookieJarSettings;
if (!cookieJarSettings) {
// Although the variable is called 'triggering principal', it is used as the
// loading principal in the download channel, so we treat it as a loading
// principal also.
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(aTriggeringPrincipal);
cookieJarSettings =
aIsPrivate
? net::CookieJarSettings::Create(net::CookieJarSettings::ePrivate)
: net::CookieJarSettings::Create(net::CookieJarSettings::eRegular);
? net::CookieJarSettings::Create(net::CookieJarSettings::ePrivate,
shouldResistFingerprinting)
: net::CookieJarSettings::Create(net::CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
// Open a channel to the URI

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

@ -64,11 +64,11 @@ static nsContentPolicyType InternalContentPolicyTypeForFrame(
}
/* static */ already_AddRefed<LoadInfo> LoadInfo::CreateForDocument(
dom::CanonicalBrowsingContext* aBrowsingContext,
dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags) {
return MakeAndAddRef<LoadInfo>(aBrowsingContext, aTriggeringPrincipal,
return MakeAndAddRef<LoadInfo>(aBrowsingContext, aURI, aTriggeringPrincipal,
aOriginAttributes, aSecurityFlags,
aSandboxFlags);
}
@ -310,7 +310,7 @@ LoadInfo::LoadInfo(
* This constructor should only be used for TYPE_DOCUMENT loads, since they
* have a null loadingNode and loadingPrincipal.
*/
LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
nsISupports* aContextForTopLevelLoad,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags)
@ -365,12 +365,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
// for the documents' loadInfo. Note that for any other loadInfos,
// cookieBehavior will be BEHAVIOR_REJECT for security reasons.
bool isPrivate = mOriginAttributes.mPrivateBrowsingId > 0;
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting_dangerous(
aURI, mOriginAttributes,
"We are creating CookieJarSettings, so we can't have one already.");
mCookieJarSettings = CookieJarSettings::Create(
isPrivate ? CookieJarSettings::ePrivate : CookieJarSettings::eRegular);
isPrivate ? CookieJarSettings::ePrivate : CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
nsIPrincipal* aTriggeringPrincipal,
nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal,
const OriginAttributes& aOriginAttributes,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags)
: mTriggeringPrincipal(aTriggeringPrincipal),
@ -407,8 +412,13 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
// for the documents' loadInfo. Note that for any other loadInfos,
// cookieBehavior will be BEHAVIOR_REJECT for security reasons.
bool isPrivate = mOriginAttributes.mPrivateBrowsingId > 0;
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting_dangerous(
aURI, mOriginAttributes,
"We are creating CookieJarSettings, so we can't have one already.");
mCookieJarSettings = CookieJarSettings::Create(
isPrivate ? CookieJarSettings::ePrivate : CookieJarSettings::eRegular);
isPrivate ? CookieJarSettings::ePrivate : CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
LoadInfo::LoadInfo(dom::WindowGlobalParent* aParentWGP,
@ -1000,10 +1010,13 @@ LoadInfo::GetCookiePolicy(uint32_t* aResult) {
namespace {
already_AddRefed<nsICookieJarSettings> CreateCookieJarSettings(
nsContentPolicyType aContentPolicyType, bool aIsPrivate) {
nsContentPolicyType aContentPolicyType, bool aIsPrivate,
bool shouldResistFingerprinting) {
if (StaticPrefs::network_cookieJarSettings_unblocked_for_testing()) {
return aIsPrivate ? CookieJarSettings::Create(CookieJarSettings::ePrivate)
: CookieJarSettings::Create(CookieJarSettings::eRegular);
return aIsPrivate ? CookieJarSettings::Create(CookieJarSettings::ePrivate,
shouldResistFingerprinting)
: CookieJarSettings::Create(CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
// These contentPolictTypes require a real CookieJarSettings because favicon
@ -1011,11 +1024,13 @@ already_AddRefed<nsICookieJarSettings> CreateCookieJarSettings(
// send/receive cookies.
if (aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON ||
aContentPolicyType == nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
return aIsPrivate ? CookieJarSettings::Create(CookieJarSettings::ePrivate)
: CookieJarSettings::Create(CookieJarSettings::eRegular);
return aIsPrivate ? CookieJarSettings::Create(CookieJarSettings::ePrivate,
shouldResistFingerprinting)
: CookieJarSettings::Create(CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
return CookieJarSettings::GetBlockingAll();
return CookieJarSettings::GetBlockingAll(shouldResistFingerprinting);
}
} // namespace
@ -1024,8 +1039,12 @@ NS_IMETHODIMP
LoadInfo::GetCookieJarSettings(nsICookieJarSettings** aCookieJarSettings) {
if (!mCookieJarSettings) {
bool isPrivate = mOriginAttributes.mPrivateBrowsingId > 0;
mCookieJarSettings =
CreateCookieJarSettings(mInternalContentPolicyType, isPrivate);
nsCOMPtr<nsIPrincipal> loadingPrincipal;
Unused << this->GetLoadingPrincipal(getter_AddRefs(loadingPrincipal));
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(loadingPrincipal);
mCookieJarSettings = CreateCookieJarSettings(
mInternalContentPolicyType, isPrivate, shouldResistFingerprinting);
}
nsCOMPtr<nsICookieJarSettings> cookieJarSettings = mCookieJarSettings;

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

@ -63,7 +63,7 @@ class LoadInfo final : public nsILoadInfo {
// Used for TYPE_DOCUMENT load.
static already_AddRefed<LoadInfo> CreateForDocument(
dom::CanonicalBrowsingContext* aBrowsingContext,
dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
const OriginAttributes& aOriginAttributes, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags);
@ -94,14 +94,15 @@ class LoadInfo final : public nsILoadInfo {
// Constructor used for TYPE_DOCUMENT loads which have a different
// loadingContext than other loads. This ContextForTopLevelLoad is
// only used for content policy checks.
LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIPrincipal* aTriggeringPrincipal,
LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
nsISupports* aContextForTopLevelLoad, nsSecurityFlags aSecurityFlags,
uint32_t aSandboxFlags);
private:
// Use factory function CreateForDocument
// Used for TYPE_DOCUMENT load.
LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext, nsIURI* aURI,
nsIPrincipal* aTriggeringPrincipal,
const OriginAttributes& aOriginAttributes,
nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags);

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

@ -429,15 +429,19 @@ already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
already_AddRefed<nsICookieJarSettings> CookieCommons::GetCookieJarSettings(
nsIChannel* aChannel) {
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(aChannel);
if (aChannel) {
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
nsresult rv =
loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
if (NS_WARN_IF(NS_FAILED(rv))) {
cookieJarSettings = CookieJarSettings::GetBlockingAll();
cookieJarSettings =
CookieJarSettings::GetBlockingAll(shouldResistFingerprinting);
}
} else {
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::eRegular);
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
MOZ_ASSERT(cookieJarSettings);

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

@ -84,16 +84,17 @@ class ReleaseCookiePermissions final : public Runnable {
} // namespace
// static
already_AddRefed<nsICookieJarSettings> CookieJarSettings::GetBlockingAll() {
already_AddRefed<nsICookieJarSettings> CookieJarSettings::GetBlockingAll(
bool aShouldResistFingerprinting) {
MOZ_ASSERT(NS_IsMainThread());
if (sBlockinAll) {
return do_AddRef(sBlockinAll);
}
sBlockinAll =
new CookieJarSettings(nsICookieService::BEHAVIOR_REJECT,
OriginAttributes::IsFirstPartyEnabled(), eFixed);
sBlockinAll = new CookieJarSettings(nsICookieService::BEHAVIOR_REJECT,
OriginAttributes::IsFirstPartyEnabled(),
aShouldResistFingerprinting, eFixed);
ClearOnShutdown(&sBlockinAll);
return do_AddRef(sBlockinAll);
@ -101,7 +102,7 @@ already_AddRefed<nsICookieJarSettings> CookieJarSettings::GetBlockingAll() {
// static
already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
CreateMode aMode) {
CreateMode aMode, bool aShouldResistFingerprinting) {
MOZ_ASSERT(NS_IsMainThread());
RefPtr<CookieJarSettings> cookieJarSettings;
@ -111,7 +112,8 @@ already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
case ePrivate:
cookieJarSettings = new CookieJarSettings(
nsICookieManager::GetCookieBehavior(aMode == ePrivate),
OriginAttributes::IsFirstPartyEnabled(), eProgressive);
OriginAttributes::IsFirstPartyEnabled(), aShouldResistFingerprinting,
eProgressive);
break;
default:
@ -126,21 +128,26 @@ already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
nsIPrincipal* aPrincipal) {
MOZ_ASSERT(NS_IsMainThread());
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(aPrincipal);
if (aPrincipal && aPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0) {
return Create(ePrivate);
return Create(ePrivate, shouldResistFingerprinting);
}
return Create(eRegular);
return Create(eRegular, shouldResistFingerprinting);
}
// static
already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
uint32_t aCookieBehavior, const nsAString& aPartitionKey,
bool aIsFirstPartyIsolated, bool aIsOnContentBlockingAllowList) {
bool aIsFirstPartyIsolated, bool aIsOnContentBlockingAllowList,
bool aShouldResistFingerprinting) {
MOZ_ASSERT(NS_IsMainThread());
RefPtr<CookieJarSettings> cookieJarSettings = new CookieJarSettings(
aCookieBehavior, aIsFirstPartyIsolated, eProgressive);
RefPtr<CookieJarSettings> cookieJarSettings =
new CookieJarSettings(aCookieBehavior, aIsFirstPartyIsolated,
aShouldResistFingerprinting, eProgressive);
cookieJarSettings->mPartitionKey = aPartitionKey;
cookieJarSettings->mIsOnContentBlockingAllowList =
aIsOnContentBlockingAllowList;
@ -151,18 +158,20 @@ already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
// static
already_AddRefed<nsICookieJarSettings> CookieJarSettings::CreateForXPCOM() {
MOZ_ASSERT(NS_IsMainThread());
return Create(eRegular);
return Create(eRegular, /* shouldResistFingerprinting */ false);
}
CookieJarSettings::CookieJarSettings(uint32_t aCookieBehavior,
bool aIsFirstPartyIsolated, State aState)
bool aIsFirstPartyIsolated,
bool aShouldResistFingerprinting,
State aState)
: mCookieBehavior(aCookieBehavior),
mIsFirstPartyIsolated(aIsFirstPartyIsolated),
mIsOnContentBlockingAllowList(false),
mIsOnContentBlockingAllowListUpdated(false),
mState(aState),
mToBeMerged(false),
mShouldResistFingerprinting(false) {
mShouldResistFingerprinting(aShouldResistFingerprinting) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT_IF(
mIsFirstPartyIsolated,
@ -411,6 +420,7 @@ void CookieJarSettings::Serialize(CookieJarSettingsArgs& aData) {
RefPtr<CookieJarSettings> cookieJarSettings = new CookieJarSettings(
aData.cookieBehavior(), aData.isFirstPartyIsolated(),
aData.shouldResistFingerprinting(),
aData.isFixed() ? eFixed : eProgressive);
cookieJarSettings->mIsOnContentBlockingAllowList =

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

@ -121,11 +121,13 @@ class CookieJarSettings final : public nsICookieJarSettings {
NS_DECL_NSICOOKIEJARSETTINGS
NS_DECL_NSISERIALIZABLE
static already_AddRefed<nsICookieJarSettings> GetBlockingAll();
static already_AddRefed<nsICookieJarSettings> GetBlockingAll(
bool aShouldResistFingerprinting);
enum CreateMode { eRegular, ePrivate };
static already_AddRefed<nsICookieJarSettings> Create(CreateMode aMode);
static already_AddRefed<nsICookieJarSettings> Create(
CreateMode aMode, bool aShouldResistFingerprinting);
static already_AddRefed<nsICookieJarSettings> Create(
nsIPrincipal* aPrincipal);
@ -136,7 +138,8 @@ class CookieJarSettings final : public nsICookieJarSettings {
static already_AddRefed<nsICookieJarSettings> Create(
uint32_t aCookieBehavior, const nsAString& aPartitionKey,
bool aIsFirstPartyIsolated, bool aIsOnContentBlockingAllowList);
bool aIsFirstPartyIsolated, bool aIsOnContentBlockingAllowList,
bool aShouldResistFingerprinting);
static CookieJarSettings* Cast(nsICookieJarSettings* aCS) {
return static_cast<CookieJarSettings*>(aCS);
@ -184,7 +187,7 @@ class CookieJarSettings final : public nsICookieJarSettings {
};
CookieJarSettings(uint32_t aCookieBehavior, bool aIsFirstPartyIsolated,
State aState);
bool aShouldResistFingerprinting, State aState);
~CookieJarSettings();
uint32_t mCookieBehavior;

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

@ -144,7 +144,7 @@ static auto CreateDocumentLoadInfo(CanonicalBrowsingContext* aBrowsingContext,
} else {
OriginAttributes attrs;
aBrowsingContext->GetOriginAttributes(attrs);
loadInfo = LoadInfo::CreateForDocument(aBrowsingContext,
loadInfo = LoadInfo::CreateForDocument(aBrowsingContext, aLoadState->URI(),
aLoadState->TriggeringPrincipal(),
attrs, securityFlags, sandboxFlags);
}

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

@ -89,8 +89,11 @@ void SetACookieInternal(nsICookieService* aCookieService, const char* aSpec,
nsIContentPolicy::TYPE_OTHER);
nsCOMPtr<nsICookieJarSettings> cookieJarSettings =
aAllowed ? CookieJarSettings::Create(CookieJarSettings::eRegular)
: CookieJarSettings::GetBlockingAll();
aAllowed
? CookieJarSettings::Create(CookieJarSettings::eRegular,
/* shouldResistFingerprinting */ false)
: CookieJarSettings::GetBlockingAll(
/* shouldResistFingerprinting */ false);
MOZ_ASSERT(cookieJarSettings);
nsCOMPtr<nsILoadInfo> loadInfo = dummyChannel->LoadInfo();

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

@ -388,8 +388,10 @@ bool StoragePrincipalHelper::ShouldUsePartitionPrincipalForServiceWorker(
cookieJarSettings = document->CookieJarSettings();
} else {
// If there was no document, we create one cookieJarSettings here in order
// to get the cookieBehavior.
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::eRegular);
// to get the cookieBehavior. We don't need a real value for RFP because
// we are only using this object to check default cookie behavior.
cookieJarSettings = CookieJarSettings::Create(
CookieJarSettings::eRegular, /* shouldResistFingerpreinting */ false);
}
// We only support partitioned service workers when dFPI is enabled.

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

@ -383,14 +383,18 @@ nsresult WebExecutorSupport::CreateStreamLoader(
channel->SetLoadFlags(nsIRequest::LOAD_ANONYMOUS);
}
bool shouldResistFingerprinting =
nsContentUtils::ShouldResistFingerprinting(channel);
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
if (aFlags & java::GeckoWebExecutor::FETCH_FLAGS_PRIVATE) {
nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(channel);
NS_ENSURE_TRUE(pbChannel, NS_ERROR_FAILURE);
pbChannel->SetPrivate(true);
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::ePrivate);
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::ePrivate,
shouldResistFingerprinting);
} else {
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::eRegular);
cookieJarSettings = CookieJarSettings::Create(CookieJarSettings::eRegular,
shouldResistFingerprinting);
}
MOZ_ASSERT(cookieJarSettings);